2012-06-25 4 views
6

ドメイン情報を含む文書を持つdomainコレクションがあります。そのうちの1つは、歴史的なwhoisレコードです。これは、ゼロ以上で、ドキュメントのスペースの大半を占めています。MongoDB:ドキュメントを保存するとドキュメント全体が書き換えられますか?

ドキュメント全体を読み込んだ場合、小さいフィールド(数字フィールドを更新するようなもの)を変更してsave()メソッドを使用すると、ドキュメント全体がディスクにフラッシュされるか、変更されたBSONのみが更新されますか?最終的に私の質問は、update()のコードをI/Oを節約するために複雑にしなければならないのですか、それともsave()を使うべきですか?

これはまさに怠惰のためではなく、ドキュメント全体が読み込まれた後に、ドキュメントを変更/処理するための一連の手順を経て、変更が加えられた場合、ドキュメント全体が保存されます。しかし、文書を保存するコストが高い場合は、多分それを別の方法と考える必要があります。

答えて

4

$setで文書内の1つのフィールドを更新できます。これにより、ディスク上のフィールドが変更されます。しかし、if the document grows beyond the size before the update, the document may have to be relocated on disk。一方

here is what the documentation says about save versus update

>// x is some JSON style object 
>db.mycollection.save(x); // updates if exists; inserts if new 
> 
>// equivalent to: 
>db.mycollection.update({ _id: x._id }, x, /*upsert*/ true); 

参照

+0

これは役に立ちますが、実際には私の質問には答えません。私が10MBのBSON文書を持っていれば、それは1つのプロパティを変更して読み込み、それを保存して10MBのフルをもう一度書きますか?文書を再配置する必要がないと仮定します。 –

+0

MongoDBがメモリマップされたファイルを使用しているという事実は、* "は書かれたものです" *の詳細を参考にしてください。 1つのプロパティだけを更新すると、理想的にはそれらのバイトだけがディスクにフラッシュされます。しかし、BSONが十分に変更されれば、すべてをディスクにフラッシュすることになります。 –

+1

@GatesVP:ページ全体が汚れていると考えられ、洗い流さなければなりません。 –

2

これは、使用しているクライアントライブラリによって異なります。たとえば、Mongoid(RubyのODM)は、($setコマンドを使用して)変更されたフィールドだけを送信するほどスマートです。時にはスマートすぎてネストされたハッシュに対して行った変更をキャッチしません。しかし、私はそれが未変更のフィールドを送信することを見たことがない。

他のライブラリ/ドライバは、動作が異なる場合があります。

0

私はこの質問が古いことを知っていますが、データベース構造を設計する上でどのように役立つかを知ることは非常に便利です。 MongoDBのストレージエンジンの詳細は以下の通りです: https://docs.mongodb.com/v3.2/faq/storage/

この文書は質問に答えています。基本的には、MongoDBの整数フィールドを更新すると、整数が存在するメモリ内のページ(通常は4k)をダーティにマークし、次のディスクフラッシュ時にメモリページをディスクに書き込みます。したがって、ドキュメントのサイズが非常に大きい場合、ドキュメントの一部しかディスクに書き込まれない可能性があります。

しかし、他にも多くの場合があります。より多くのデータを文書に埋め込む場合、MongoDBは文書全体を新しい場所に移動して文書を拡大する必要があります。その場合、文書全体がディスクに書き込まれます。

関連する問題