Article {
"_id" : "A",
"title" : "Hello World",
"user_id" : 12345,
"text" : 'My test article',
"comments" : [
{ 'text' : 'blah', 'user_id' : 654321, 'votes' : [987654]},
{ 'text' : 'foo', 'user_id' : 987654, 'votes' : [12345, 654321] },
...
]
}
ここでの基本的な前提は、Comments
をネストしたことです。 Article
の内部 。 Votes
Comments
にのみ適用されます 、したがって、各Comment
の配列として保存されています 。この場合、user_idを保存しました。より多くの情報(time_createdなど)を保存したい場合は、オブジェクトの配列に投票できます:
... 'votes' : [ { user_id : 987654, ts : 78946513 } ] ...
クエリを効率的に実行する方法:
db.articles.find( { _id : 'A' } )
これにより、1つのクエリですべてが取得されます。コメントごとの開票をカウントするには、クライアント側のロジックを実行する必要があるかもしれませんが、これは非常に簡単です。
db.articles.ensureIndex( { "comments.user_id" : 1 } )
db.articles.find( { "comments.user_id" : 987654 } ) // returns all document fields
インデックスを使用すると、ドキュメント内のコメントを効率的に検索できます。
現在、サブ配列から一致のみを抽出する方法はありません。このクエリは、実際には、そのユーザーによるコメントを含むすべての記事を返します。これがデータ量が多すぎる可能性がある場合は、トリミングを行うことができます。
db.articles.find( { "comments.user_id" : 987654 }, { "title" : 1, "comments.user_id" : 1 })
db.articles.ensureIndex( { "comments.votes" : 1 } )
db.articles.find( { "comments.votes" : 987654 } )
繰り返しになりますが、これにより、コメントだけでなく、すべての記事が返されます。
ここではトレードオフが必要です。記事を返すと、データが多すぎるように見える場合があります。しかし、クエリ#3を実行するときに、ユーザーに何を表示する予定ですか?
「私が投票したコメント」のリストを取得する コメント自体がなければ、それほど有用ではありません。もちろん、コメントは記事自体(または少なくともタイトルだけ)なしではあまり役に立ちません。
ほとんどの場合、クエリ#3はVotes
からの結合に発展します Comments
へ Articles
。その場合は、最初に記事を元に戻してみませんか?