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