Meteor:如何只为集合中的每个值返回一个条目

时间:2015-11-25 10:03:13

标签: javascript meteor meteor-helper

我目前正在开发一款也具有聊天功能的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查询)?

(我已经尝试了很多东西并在文档中搜索了答案,但是这样做很麻烦。任何帮助都会非常感激。)

1 个答案:

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