MongoDB - получить 1 последнее сообщение от каждого разговора? - PullRequest
2 голосов
/ 25 марта 2012

У меня есть коллекция для разговоров:

{_id: ..., from: userA, to: userB, message: "Hello!", datetime: ...}

Я хочу показать предварительный просмотр разговоров пользователя - последнее сообщение от каждого разговора между текущим пользователем и любыми другими пользователями.Поэтому, когда пользователь нажимает на какое-то «последнее сообщение», он переходит на следующую страницу со всеми сообщениями между ним и этим пользователем.

Как мне это сделать (получить 1 последнее сообщение из каждого разговора) без Map / Reduce?

1) использовать "отличную" команду?(как?)

2) установить флаг "последний" для последнего сообщения?Я думаю, что это не очень безопасно ...

3) ..?

1 Ответ

3 голосов
/ 25 марта 2012

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

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

  • Поместите поле хеша / объекта в вашего пользователя с именем most_recent_conversations
  • Когда вы вступаете в новый разговор с другим пользователем, обновите его так, чтобы он выглядел следующим образом:

    previewUser.most_recent_conversations[userConversedWith._id] = newestConversation._id
    
  • Каждый раз, когда вы начинаете новую беседу, просто измените значение для пользователей, участвующих в их хэше, с новым идентификатором беседы. Теперь у нас есть структура { uid: conversationId, ... }, которая в основном является данными предварительного просмотра, которые нам нужны.

  • Теперь вы можете просмотреть самый последний разговор (или N разговоров, если вы сделаете каждое значение хеша массивом) просто:

    var previewUser = db.users.findOne({ _id: someId });
    var recentIds = [];
    for( uid in previewUser.most_recent_conversations ) {
      recentIds.push( previewUser.most_recent_conversations[uid] );
    }
    var recentConversations = db.conversations.find({
      _id: { $in: recentIds }
    });
    
...