问题
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._idEvery 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