MongoDB запросов / моделирования тысяч - PullRequest
2 голосов
/ 07 декабря 2011

Модель

У меня есть коллекция ChatRoom:

ObjectId Id
ObjectId GroupId 
ObjectId LastMessageId 
List<ObjectId> Members 
bool IsEveryone

У меня есть коллекция ChatMessage:

ObjectId GroupId
ObjectId RoomId
ObjectId Id
ObjectId UserId
string Text
DateTime Date

Фон

Каждый пользователь является частью нескольких групп. Каждая группа содержит несколько комнат. У меня есть все комнаты, частью которых является пользователь, и массив идентификаторов последних сообщений, которые пользователь видел до сих пор.

Идея состоит в том, чтобы вычислить дельту для данного пользователя : (1) вернуть все последние идентификаторы сообщений из всех комнат и (2) вычислить, сколько сообщений чата пропустил пользователь (новые сообщения) ,

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

Запрос

Я ищу способ выполнить 2 быстрых запроса для:

  1. Возвращает идентификатор последнего сообщения для комнаты (по дате, desc). Ввод : массив номера комнаты. Вывод : массив [номер комнаты]: [идентификатор сообщения]

  2. Подсчитайте, сколько новых сообщений (целых) существует на комнату для данного пользователя . Ввод : массив [идентификатор пользователя, номер комнаты, дата последнего сообщения]. Вывод : массив [номер комнаты]: [int]. Обратите внимание, что я не хочу считать сообщения, написанные пользователем.

Можете ли вы помочь с построением оптимизированных запросов? Я использую MongoDB C # 10gen SDK.

UPDATE:

Каждый раз, когда я сейчас пишу новое сообщение чата, я также запускаю атомарное обновление в ChatRoom, чтобы сохранить LastMessageId. Это решает первый запрос, сохраняя при этом разумность (скорость чтения> скорость записи).

1 Ответ

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

Собираюсь ответить на ваши вопросы .:

1. Для достижения наилучшей производительности необходимо создать правильный составной индекс:

db.ChatMessage.ensureIndex({GroupId: 1, RoomId:1, Date: -1})

Тогда запрос будет выглядеть так:

db.ChatMessage.find({GroupId: 2, RoomId:3}).sort({"Date": -1})

Если вам нужно вернуть только {RoomId, MessageId} объект, вы можете указать следующие поля:

db.ChatMessage.find({GroupId: 2, RoomId:3}, //filter messages
             {RoomId:1, _id:1}) // specify set of fields thats query should return
             .sort({"Date": -1}) // sort by date desc
             .limit(10) // take a specific number of last messagies

Чтобы убедиться, что запрос использует правильный индекс, вы можете использовать метод объяснение () .

2. В качестве второго вопроса я предлагаю предварительно пересчитать количество новых сообщений, используя оператор set , вместо того, чтобы использовать map / reduce, поскольку он работает медленно для больших наборов данных. Или другой хороший вариант может быть добавочный асинхронное отображение / уменьшить.

В зависимости от ваших потребностей в коллекции комнат вы можете иметь NumberOfNewMessagies или вложенный массив [{UserId, MessagiesCount}]. Поэтому, когда вы загрузите комнату, у вас всегда будет много новых сообщений.

Кстати, дайте мне знать, если у вас возникнут проблемы с преобразованием запросов оболочки mongodb в код на C #.

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

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