この回答を他の回答の後に投稿するので、言及したことのいくつかを繰り返します。この回答ではなく、最初の適切な回答を受け入れてください。
とはいえ、考慮すべき点がいくつかあります。次の 3 つの質問を検討してください。
- 投稿のクエリを実行するたびに、常にすべてのコメントが必要ですか?
- コメントを直接クエリしますか (特定のユーザーのコメントをクエリするなど)?
- システムの使用率は比較的低いですか?
すべての質問に「はい」と答えられる場合は、コメント配列を埋め込むことができます。他のすべてのシナリオでは、コメントを保存するために別のコレクションが必要になるでしょう。
まず第一に、実際には同時実行安全な方法でアトミックにコメントを更新および削除できます (位置演算子による更新を参照) が、インデックス ベースの挿入など、実行できないことがいくつかあります。
あらゆる種類の大規模なコレクションに埋め込み配列を使用する際の主な懸念は、move-on-update の問題です。db.col.stats().paddingFactor
MongoDB は、ドキュメントが必要に応じて拡大できるように、ドキュメントごとに一定量のパディング (「参考文献」を参照) を予約しています。このパディングを使い果たした場合(ユースケースでよくあることです)、ディスク上で増え続けるドキュメントを移動する必要があります。これにより、更新が桁違いに遅くなるため、高帯域幅のサーバーでは深刻な問題になります。関連するものの、それほど重要ではない問題に帯域幅があります。最初の 10 件のみを表示しているにもかかわらず、すべてのコメントを含む投稿全体をクエリする以外に選択肢がない場合は、かなりの帯域幅を浪費することになり、特にクラウド環境で問題になる可能性があります ($ を使用できます)。これの一部を避けるためにスライスします)。
ここに組み込みたい場合は、基本的な操作を次に示します。
コメントを追加する :
db.posts.update({_id:[POST ID]}, {$push:{comments:{commentId:"remon-923982", author:"Remon", text:"Hi!"}}})
コメントを更新:
db.posts.update({_id:[POST ID], 'comments.commentId':"remon-923982"}, {$set:{'comments.$.text':"Hello!"}})
コメントを削除
db.posts.update({_id:[POST ID], 'comments.commentId':"remon-923982"}, {$pull:{comments:{commentId:"remon-923982"}}})
更新基準は (プロセス全体の) 書き込みロックの一部であるため、これらのメソッドはすべて同時実行に対して安全です。
そうは言っても、おそらくコメント専用のコレクションが必要ですが、それには2番目の選択肢があります. 各コメントを専用のドキュメントに保存するか、たとえばそれぞれ 20 ~ 30 コメントのコメント バケットを使用することができます (詳細はhttp://www.10gen.com/presentations/mongosf2011/schemascaleで説明されています)。これには長所と短所があるため、どのアプローチが自分のやりたいことに最も適しているかを判断するのはあなた次第です。ページングに必要なskip(N)カーソルメソッドのo(N)パフォーマンスのために、投稿ごとのコメントが数百を超える可能性がある場合は、バケットを使用します。それ以外の場合は、ドキュメントごとにコメントするアプローチを使用してください。これは、他のユースケースのコメントに対するクエリでも最も柔軟です。