我目前正在开发一款也具有聊天功能的Meteor应用程序。
我希望列出所有会话,以显示每个会话中的最新消息。 (类似于Sample of a basic conversation overview)
假设我有一个带有变量 conversationId 的消息集合。新消息被分配一个新的conversationId,并且任何回复都将被分配第一条消息的conversationId。
要实现此会话概述,我的问题是,如何从我的收藏中仅返回每个conversationId的最新条目?
这是我被困的地方:
Template.tabsTwo.helpers({
messages: function () {
//to retrieve all messages from the logged in user, then retrieve the conversationIDs and drop duplicates
var userMessages = Messages.find({senderId: Meteor.userId()}, {sort: {date_created: -1, subject: -1}});
var userConversationIds = userMessages.map((function(a) {
return a.conversationId;
}));
var uniqueConversationIDs = [];
$.each(userConversationIds, function(i, el){
if($.inArray(el, uniqueConversationIDs) === -1) uniqueConversationIDs.push(el);
});
return Messages.find({conversationId: {$in:uniqueConversationIDs}}, {sort: {date_created: -1}});
}
});
这仍然让我回复所有消息。我现在问自己,如果我可以修改此查询以使其工作或者我需要以不同的方式处理它(例如,执行循环和.findOne查询)?
(我已经尝试了很多东西并在文档中搜索了答案,但是这样做很麻烦。任何帮助都会非常感激。)
答案 0 :(得分:0)
您的初始解决方案无效,因为您获得了会话ID列表,然后通过为这些会话查找所有消息来撤消您所做的所有工作。
一种方法是获取所有消息并通过对话对其进行分组,然后在每个分组中选择最新消息。这是一个这样的解决方案:
// Fetch this user's messages.
var userMessages = Messages
.find({senderId: Meteor.userId()})
.fetch();
var firstMessages = _.chain(userMessages)
// Group all of the messages by conversation.
.groupBy('conversationId')
.map(function(messages) {
// For each message in this conversation's messages, choose the
// first one by date.
return _.chain(messages)
.sortBy(function(message) {return -message.created_at;})
.first()
.value();
}).value();
return firstMessages;
firstMessages
是一组消息文档,其中包含当前用户在他/她参与的每个对话中添加的第一条消息。您可以从帮助者那里返回该值,但如果您不喜欢要返回游标,只需添加以下内容:
var messageIds = _.pluck(userMessages, '_id');
return Messages.find({_id: {$in: messageIds}});