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
применяется только к Comment
, поэтому они хранятся в виде массива с каждым Comment
.В этом случае я только что сохранил user_id.Если вы хотите хранить больше информации (time_created и т. Д.), То вы можете проголосовать за массив объектов:
... 'votes' : [ { user_id : 987654, ts : 78946513 } ] ...
Как эффективно выполнять ваши запросы:
- получить статью A, комментарии к статье A и количество голосов в комментариях
db.articles.find( { _id : 'A' } )
Все получится одним запросом.Возможно, вам придется выполнить некоторую клиентскую логику для подсчета голосов за комментарий, но это довольно тривиально.
- получить все комментарии пользователя B по всем статьям
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 })
- получить все комментарии Пользователь B проголосовал за
db.articles.ensureIndex( { "comments.votes" : 1 } )
db.articles.find( { "comments.votes" : 987654 } )
Опять же, это вернет все статьи, а не только комментарии.
Здесь нужно найти компромисс.Возвращение статьи может показаться, что мы возвращаем слишком много данных.Но что вы планируете показывать пользователю, когда делаете запрос № 3?
Получение списка "комментариев, за которые я голосовал" , не очень полезно без самого комментария.Конечно, комментарий не очень полезен без самой статьи (или хотя бы только заголовка).
В большинстве случаев запрос № 3 превращается в соединение от Votes
до Comments
до Articles
.Если это так, то почему бы просто не вернуть статьи для начала?