Проектирование базы данных MongoDB - много ли встроенных документов в порядке? - PullRequest
1 голос
/ 15 марта 2011

Я пытаюсь создать базу данных MongoDB для простой системы голосования. Если бы я нарисовал схему, она бы выглядела примерно так:

User {
    name: String
  , email: String
}

Vote {
    message: String
  , voters: [ObjectId(User._id)]
}

У меня есть несколько вопросов об этом дизайне, когда на один голос приходится много избирателей:

  1. Отправка всего массива избирателей на сторону клиента (не говоря уже о кэшировании его в памяти) стоит очень дорого, верно? Есть ли способ получить голосование "мелким" способом, поэтому, когда мне понадобится voice.voters, он отправит еще один запрос в базу данных массиву избирателей?
  2. Если избиратель уже проголосовал, я хочу это проверить и не считать его голос. Для этого можно ли выполнить запрос в массиве встроенных избирателей, чтобы быстро найти его?
  3. При отображении голосов я бы хотел показать количество голосов без извлечения массива избирателей на стороне клиента. Могу ли я выполнить какой-нибудь запрос на подсчет длины избирателей?

Ответы [ 2 ]

1 голос
/ 15 марта 2011

Я бы добавил немного избыточности в схему, чтобы избежать некоторых потенциальных проблем, о которых вы упомянули. Я предполагаю, что вы хотите 1) быстро подсчитать количество голосов и 2) убедиться, что пользователь не может голосовать дважды.

Один из способов добиться этого - сохранить как список пользователей, так и количество голосов, и добавить в запрос на обновление пункт, который гарантирует, что голос добавляется только в том случае, если идентификатор пользователя отсутствует в списке избирателей. :

var query = {_id: xyz, voters: {$ne: user_id}
var update = {$inc: {votes: 1}, $push: {voters: user_id}}
db.votes.update(query, update, true)

(последний параметр - upsert, очень приятная особенность Mongo)

Затем, если вы хотите показать количество голосов, вы можете ограничить свойства результата до свойства votes:

db.votes.find({_id: xyz}, {votes: true})

Полное описание того, что вы хотите сделать, вы можете найти здесь: http://cookbook.mongodb.org/patterns/votes/

0 голосов
/ 15 марта 2011

1) Можно указать только для возврата подмножества полей клиенту ( документы ).
например найти конкретное сообщение и вернуть только «AnotherField».

db.Vote.find({ message : "search for this message" }, { AnotherField : 1 } );

2) Вы можете использовать оператор $ addToSet для добавления избирателя в массив избирателей ( документы ), который (цитата):

Добавляет значение в массив, только если его уже не в массиве

, например

{ $addToSet : { voters: "Bob"} }

3) Вы можете сохранить счет как дополнительное поле в документе, а затем просто вернуть его.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...