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" ] } } ])
逻辑说明
- 收集所有层级文档:通过
$concatArrays和$reduce,把根文档、embedded数组的每个元素、以及每个embedded元素中的nested数组(如果存在)全部合并到一个数组中,确保所有层级的updatedAt都能参与比较。 - 筛选最新文档:展开数组后按
updatedAt降序排序,分组后取第一个元素就是更新时间最晚的文档。 - 重组结构:把筛选出的最新文档放到
embedded数组中,同时保留根文档的原始_id和updatedAt。
扩展说明
如果你的文档存在更深层次的嵌套(比如nested数组里还有子数组),可以在$reduce中递归处理嵌套数组,或者使用$function(MongoDB 4.4+支持)来递归遍历所有层级的文档,确保所有元素都被纳入比较范围。
内容的提问来源于stack exchange,提问作者Srikar
相关产品推荐
相关产品推荐

