web-dev-qa-db-ja.com

更新と置換のMongodbの意味

私は この関連する質問 を読みましたが、以下のものは異なります。 mongodb c#ドライバには、ドキュメントコレクションクラスにReplaceOneメソッド(および非同期の対応物)があり、これを使用して、フィルター引数に適合するドキュメントのコンテンツ全体を置き換えることができます。別の方法は、UpdateOneまたはUpdateManyメソッド(または非同期の対応物)を使用することです。これには、UpdateDefinition<TDocument>の構築が必要です。

私の質問は、同じ結果を達成するためにどちらかを選択するのに十分な入力データがある場合に、これらの方法の1つを他のものよりも選択することの意味(replace vs update)に関係しています。つまり、元のドキュメント全体があり、その内容のごく一部のみを更新したい場合。

最初に考えることができる要素は、データベースサーバーに送信されるペイロードです。私はmongodb c#ドライバーのソースを何も読んでおらず、これを確認するためのドキュメントを見つけることができませんでしたが、ReplaceOneは、特に大きなドキュメントの場合、更新操作でより多くのバイトを送信する必要があるようです。 Update...メソッドは、変更が必要なドキュメントのスライスの更新メタデータのみを送信することで(両方のメソッドが送信する必要があるフィルター基準に加えて)、より小さなペイロードで済むようです。これが正確な仮定であるかどうか誰でも確認できますか?

同僚が持ち出したもう1つの要因は、メソッドの選択(更新と置換)がドキュメントのインデックス作成にも影響する可能性があることです。ここでの前提は、ReplaceOneを使用すると、更新中のドキュメントのすべてのインデックスがデータベースに再構築される可能性があるのに対し、Update...メソッドには十分な変更メタデータ情報があり、更新定義のメタデータの一部ではありません。 mongodbが内部的にドキュメントインデックスの構築を処理するかどうかを、置換と更新のどちらを使用してドキュメントを変更するかによって検証できますか?

Update<TDefinition>クラスのAddToSetおよびPullFilterメソッドに関して、3番目の要素がすでに数回出てきました。 Update...メソッドでは、(json配列のような)ドキュメント内のセットにアイテムを追加すると同時に削除することはできません。これらの操作は、Update...メソッドへの2つの個別の呼び出しと個別のUpdate<TDefinition>インスタンス(同じフィルター引数を使用)を使用して、個別に送信する必要があります。この場合、ReplaceOneメソッドは、少なくともC#ドライバーを使用する場合に、この種のドキュメントを単一の「トランザクション」で変更する唯一の方法のようです。代替案が上記のようにインデックス作成に悪影響を与えるかどうかは不明なので、現在はReplaceOneではなくUpdate...を使用しています。

これら以外に、Update...ファミリよりもReplaceOneファミリのメソッドから選択する、またはその逆につながる可能性がある追加の影響は何ですか?繰り返しますが、これは、どちらのアプローチでも同じ結果を達成するのに十分な入力データ(つまり、すべてのドキュメントデータ)があり、状態を直接(置換によって)変更することを気にせず、mongo定義を(更新によって)構築することを気にしないことを前提としています。 。

20
danludwig

Mongoデータは構造化されていないので、replaceOneとUpdateの主な利点は、すべてのフィールドが削除されて新しいドキュメントに置き換えられ、クエリがより簡単になることです。

1)はい、ただし問題は最小限ですが、検索条件は両方で同じですが、replaceOneはドキュメント全体をクエリで渡す必要がありますが、完全な新しいドキュメントがあり、それを確実にしたい場合には価値があります。その方法で終了

2)置換時にインデックスを再作成->はい、replaceOneは既存のものを更新する代わりにドキュメント全体を置き換えます。インデックスにある要素で更新する場合、インデックスは変更に再調整する必要がありますが、置換では常に再調整。 _idインデックスは両方の操作の影響を受けません(私は思う)

3)希望する値がすでにある場合、単一のフィールドを変更するためにドキュメント全体を置き換える必要はなく、すべてのフィールドによってインデックスが再作成されるため、そのために$ set操作を使用する必要があります。ドキュメント全体ではなく単一のフィールドのReplaceOneと考える

https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/index.htmlhttps://docs.mongodb.com/manual/reference/ operator/update/set /

1
zero

RESTサービスに組み込まれている場合、replaceOneメソッドはPUT操作とうまく連携し、オブジェクト全体とともにオブジェクト全体をリクエスト本文で送信し、これを永続化できます。 PUT操作の際立った特徴は、べき等であることです(繰り返し実行できます)。replaceOneは、デフォルトでfalseになるupsertオプションを取りますが、これががtrueに設定されていて(検索条件が一意にインデックス付けされたフィールドにあった場合)、ドキュメントが個別に削除されたかどうかに関係なく、操作を繰り返し実行できるようになります。

更新操作は、POST操作に似ています。これは、完全に置き換えるのではなく、ドキュメントの一部を更新するだけだからです。また、upsertオプションをとりますが、ドキュメントが別のプロセスによって削除された場合、結果のドキュメントが不正な形式になり、更新が失敗する可能性があります。

0
robjwilkins