【问题标题】:Meteor: How to return only one entry for each value from collectionMeteor:如何为集合中的每个值仅返回一个条目
【发布时间】:2016-02-28 01:34:33
【问题描述】:

我目前正在开发一个同时具有聊天功能的 Meteor 应用程序。

我想要一个包含所有对话的列表,其中显示每个对话中的最新消息。 (类似于Sample of a basic conversation overview

假设我有一个带有变量conversationId 的集合Messages。新消息被分配一个新的会话 ID,任何回复都将被分配第一条消息的会话 ID。

要实现此对话概览,我的问题是,如何从我的集合中仅返回每个对话 ID 的最新条目?

这是我卡住的地方:

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 中搜索了答案,但在正确解决这个问题时遇到了麻烦。任何帮助将不胜感激。)

【问题讨论】:

  • 由于这必须在客户端运行,我认为您应该在消息中添加一个isLatest 字段并在每次发送消息时更新它,或者执行findOne 循环。因为它是minimongo。您可以将其作为一个两步过程来提高效率(助手中的助手),从而降低重新计算的成本。

标签: javascript meteor meteor-helper


【解决方案1】:

您的初始解决方案不起作用,因为您正在获取对话 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}});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    相关资源
    最近更新 更多