Meteor:如何 return 集合中的每个值只有一个条目
Meteor: How to return only one entry for each value from collection
我目前正在开发一个也具有聊天功能的 Meteor 应用程序。
我想要一个所有对话的列表,显示每个对话中的最新消息。 (类似于 Sample of a basic conversation overview)
假设我有一个集合 Messages,其中包含一个变量 conversationId。新消息会分配一个新的 conversationId,任何回复都将分配第一条消息的 conversationId。
要实现此对话概述,我的问题是,我如何 return 从我的集合中仅获取每个 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 查询)?
(我已经尝试了很多东西并在文档和 SO 中搜索了答案,但是在正确解决这个问题时遇到了麻烦。任何帮助将不胜感激。)
您的初始解决方案不起作用,因为您正在获取对话 ID 列表,然后通过查找这些对话的所有 消息来撤消您所做的所有工作。
一种方法是获取所有消息并按对话对它们进行分组,然后 select 每个分组中的最新消息。这是一个这样的解决方案:
// 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
是一组消息文档,其中包含当前用户在 he/she 参与的每个对话中添加的第一条消息。您可以 return 从您的助手那里获得该值,但如果您更喜欢 return 游标,只需添加以下内容:
var messageIds = _.pluck(userMessages, '_id');
return Messages.find({_id: {$in: messageIds}});
我目前正在开发一个也具有聊天功能的 Meteor 应用程序。
我想要一个所有对话的列表,显示每个对话中的最新消息。 (类似于 Sample of a basic conversation overview)
假设我有一个集合 Messages,其中包含一个变量 conversationId。新消息会分配一个新的 conversationId,任何回复都将分配第一条消息的 conversationId。
要实现此对话概述,我的问题是,我如何 return 从我的集合中仅获取每个 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 查询)?
(我已经尝试了很多东西并在文档和 SO 中搜索了答案,但是在正确解决这个问题时遇到了麻烦。任何帮助将不胜感激。)
您的初始解决方案不起作用,因为您正在获取对话 ID 列表,然后通过查找这些对话的所有 消息来撤消您所做的所有工作。
一种方法是获取所有消息并按对话对它们进行分组,然后 select 每个分组中的最新消息。这是一个这样的解决方案:
// 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
是一组消息文档,其中包含当前用户在 he/she 参与的每个对话中添加的第一条消息。您可以 return 从您的助手那里获得该值,但如果您更喜欢 return 游标,只需添加以下内容:
var messageIds = _.pluck(userMessages, '_id');
return Messages.find({_id: {$in: messageIds}});