You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB:如何从多层嵌套文档中获取最新更新的文档?

从多层嵌入式文档中获取最后更新的文档(MongoDB聚合实现)

可以通过MongoDB的聚合管道完成这个需求,核心思路是把所有层级的文档(根文档、embedded数组元素、nested数组元素)统一收集到一个数组中,再从中筛选出更新时间最新的文档,最后重组为预期的结构。

具体聚合管道代码

db.collection.aggregate([
  // 收集所有层级的文档到一个数组,同时保留根文档的信息
  {
    $project: {
      _id: 1,
      rootUpdatedAt: "$updatedAt",
      allDocuments: {
        $concatArrays: [
          // 将根文档自身加入待比较数组
          [{ _id: "$_id", updatedAt: "$updatedAt" }],
          // 遍历embedded数组,把每个元素及其nested数组(如果存在)加入数组
          {
            $reduce: {
              input: "$embedded",
              initialValue: [],
              in: {
                $concatArrays: [
                  "$$value",
                  [ { _id: "$$this._id", updatedAt: "$$this.updatedAt" } ],
                  { $ifNull: [ "$$this.nested", [] ] }
                ]
              }
            }
          }
        ]
      }
    }
  },
  // 展开所有待比较的文档
  { $unwind: "$allDocuments" },
  // 按更新时间降序排序,最新的排在最前面
  { $sort: { "allDocuments.updatedAt": -1 } },
  // 按根文档ID分组,取第一个(最新的)文档,同时保留根文档的更新时间
  {
    $group: {
      _id: "$_id",
      updatedAt: { $first: "$rootUpdatedAt" },
      latestDoc: { $first: "$allDocuments" }
    }
  },
  // 重组为预期的输出结构
  {
    $project: {
      _id: 1,
      updatedAt: 1,
      embedded: [ "$latestDoc" ]
    }
  }
])

逻辑说明

  1. 收集所有层级文档:通过$concatArrays和$reduce,把根文档、embedded数组的每个元素、以及每个embedded元素中的nested数组(如果存在)全部合并到一个数组中,确保所有层级的updatedAt都能参与比较。
  2. 筛选最新文档:展开数组后按updatedAt降序排序,分组后取第一个元素就是更新时间最晚的文档。
  3. 重组结构:把筛选出的最新文档放到embedded数组中,同时保留根文档的原始_id和updatedAt。

扩展说明

如果你的文档存在更深层次的嵌套(比如nested数组里还有子数组),可以在$reduce中递归处理嵌套数组,或者使用$function(MongoDB 4.4+支持)来递归遍历所有层级的文档,确保所有元素都被纳入比较范围。

内容的提问来源于stack exchange,提问作者Srikar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:43:19