ограничение mongodb во встроенном документе - PullRequest
7 голосов
/ 10 декабря 2011

Мне нужно создать систему сообщений, где человек может общаться со многими пользователями. Например, я начинаю говорить с user2, user3 и user4, так что любой из них может видеть весь разговор, и если разговор не является конфиденциальным в любой момент времени, любой из участников может добавить в разговор любого другого человека.

Вот моя идея, как это сделать. Я использую Mongo, и моя идея состоит в том, чтобы использовать диалог в качестве экземпляра вместо сообщения.

Схема указана следующим образом:

{
_id : ...., // dialog Id
'private' : 0 // is the conversation private
'participants' : [1, 3, 5, 6], //people who are in the conversation
'msgs' :[
  {
   'mid' : ...// id of a message
   'pid': 1, // person who wrote a message
   'msg' : 'tafasd' //message
  },
  ....
  {
   'mid' : ...// id of a message
   'pid': 1, // person who wrote a message
   'msg' : 'tafasd' //message
  }
]
}

Я вижу некоторые плюсы для этого подхода - в большой базе данных будет легко найти сообщения для определенного разговора. - будет легко добавлять людей в разговор.

но вот проблема, для которой я не могу найти решение: разговор становится слишком длинным (возьмите в качестве примера Skype), и они не показывают вам весь разговор, они показывают вам часть, а затем они показывают вам дополнительные сообщения. В других ситуациях пропустить, лимит решает дело, но как я могу сделать это здесь?

Если это невозможно, какие у вас есть предложения?

Ответы [ 2 ]

13 голосов
/ 10 декабря 2011

Документы MongoDB объясняют, как выбрать поддиапазон элемента массива.

db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: 5}}) // first 5 comments
db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: -5}}) // last 5 comments
db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: [20, 10]}}) // skip 20, limit 10
db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: [-20, 10]}}) // 20 from end, limit 10

Вы можете использовать эту технику только для выбора сообщений, которые имеют отношение к вашему интерфейсу. Однако я не уверен, что это хороший дизайн схемы. Вы можете рассмотреть возможность отделения «видимых» сообщений от «заархивированных» сообщений. Это может сделать запрос немного легче / быстрее.

2 голосов
/ 12 декабря 2011

Существуют предостережения, если в вашем разговоре будет много много сообщений:

  1. Вы заметите значительное снижение производительности при разрезании массивов сообщений, так как mongodb загрузит их все и разделит список перед возвратом только к драйверу.
  2. Существует ограничение размера документа (16 МБ на данный момент), которое может быть достигнуто этим подходом.

Мои предложения:

  1. Используйте две коллекции: одну для разговоров, а другую для сообщений.
  2. Используйте dbref в сообщениях для разговора (индексируйте это поле с отметкой времени сообщения, чтобы иметь возможность выбирать более старые диапазоны по запросу пользователя).
  3. Дополнительное использование отдельной закрытой коллекции для каждого разговора. Будет легко найти его по имени, если вы создадите его как «разговор _»

Результат:

  • Вам придется писать все сообщения дважды. Но в отдельные коллекции это нормально.
  • Если вы хотите показать свой разговор, вам нужно будет просто выбрать все данные из одной коллекции в порядке естественной сортировки , что очень быстро.
  • Ваши закрытые коллекции будут автоматически сохранять последние сообщения и удалять старые.
  • Вы можете показать старые сообщения по запросу пользователя, запросив коллекцию основных сообщений.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...