MongoDB - get 1 last message from each conversation?

微笑、不失礼 提交于 2019-12-24 00:34:15

问题


I have a collection for conversations:

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

I want to show a preview of user's conversations - last message from each conversation between current user and any other users. So when user clicks on some "last message" he goes to next page with all messages between him and that user.

How do I do that (get 1 last message from each conversation) without Map/Reduce?

1) use "distinct" command? (how?)

2) set "last" flag for last message? I think it's not very safe...

3) ..?


回答1:


I was writing up a complicated answer to this question using cursors and a lot of advanced query features and stuff... it was painful and confusing. Then I realized, this is painful because it's not how mongodb expects you to do things really.

What I think you should do is just denormalize the data and solve this problem in one shot easily. Here's how:

  • Put a hash/object field on your User called most_recent_conversations
  • When you make a new conversation with another user, update it so that it looks like this:

    previewUser.most_recent_conversations[userConversedWith._id] = newestConversation._id
    
  • Every time you make a new conversation, simply smash the value for the users involved in their hashes with the newer conversation id. Now we have a { uid: conversationId, ... } structure which basically is the preview data we need.

  • Now you can look up the most recent conversation (or N conversations if you make each value of the hash an array!) simply:

    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 }
    });
    


来源:https://stackoverflow.com/questions/9859713/mongodb-get-1-last-message-from-each-conversation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!