Ответ 1
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
. Если это так, то почему бы просто не вернуть статьи для начала?