【问题标题】:Mongoose - Find by array of ids, but retrieve limited results (1 for each id)Mongoose - 按 id 数组查找,但检索有限的结果(每个 id 1 个)
【发布时间】:2020-01-08 01:47:30
【问题描述】:

我有我的模型称为“对话”,我的模型是“消息”,现在我想检索所有带有最后一条消息的对话(每个对话只有 1 条消息),所以我过滤了对话 ID 并查询了这些消息,但我无法为每个对话获取此消息(最后一条消息),在此先感谢。

let conversations = await ConversationModel.find({});
const conversationIds = conversations.map(conversation => conversation._id)
//  ConversationIds is basically ["conversation1", "conversation2", "conversation3"]

//  Te problem is here, i want to attach the las message for each conversation, if i put limit(1)
//  i will get 1 record for all query, but i want the last message record for each conversation.
MessageModel.find({ _id: { "$in" : conversationIds} }, ...);

【问题讨论】:

  • 如何定义对话的最后一条消息。消息文档中是否有时间、日期时间字段来解决这个问题。如果您可以在问题中提供示例文档,将大大增加问题的可见性。 MRE
  • 按日期时间,但基本上我想为每个 id 检索 1 个项目,现在任何项目都足够了
  • 因为我不知道您的文档是什么样子,所以没有发布答案,而是创建了一个示例和一个聚合查询。 See if that helps。想法是按时间戳排序,然后按$first 分组以查找最新文档。
  • 最后一个问题,我如何将您的上一个回复标记为解决方案?
  • 谢谢你,完美。

标签: javascript arrays node.js mongodb mongoose


【解决方案1】:

来自 cmets 中收集的信息;这可以在MessageModel 文档包含时间戳以识别最新文档的情况下实现。

想法: 根据conversationIds 通过$match 过滤消息,按timestamp 对它们进行排序,以便下一阶段$group 在对话参考上(比如说conversation_id)并选择其中最新的是$first accumulator。

聚合查询: playground link

db.collection.aggregate([
  {
    $match: {
      conversation_id: {
        $in: conversationIds
      }
    }
  },
  {
    $sort: {
      timestamp: -1
    }
  },
  {
    $group: {
      _id: "$conversation_id",
      latest_doc: {
        $first: "$$ROOT"
      }
    }
  }
]);

【讨论】:

    猜你喜欢
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多