如何从MongoDB嵌套文档列表中获取最新更新的文档?
如何在MongoDB中保留嵌入文档列表里最新更新的文档
可以通过聚合操作实现需求,普通查询无法直接完成数组内的筛选并仅保留最新项,以下是具体实现方案:
需求回顾
针对所有包含embedded字段的根文档,仅保留embedded数组中updatedAt时间戳最新的单个嵌入文档。
原文档结构
{ _id: "123", updatedAt: ISODate("2023-03-02T14:04:37.925+00:00"), embedded: [ { _id: "456", updatedAt: ISODate("2023-04-02T14:04:37.925+00:00") }, { _id: "789", updatedAt: ISODate("2023-04-10T14:04:37.925+00:00") } ] }
聚合管道实现方案
方案1:使用$max直接筛选最新文档
db.collection.aggregate([ // 过滤出存在embedded字段且数组非空的文档 { $match: { embedded: { $exists: true, $ne: [] } } }, // 拆分embedded数组为单个文档 { $unwind: "$embedded" }, // 按根文档_id分组,提取最新嵌入文档 { $group: { _id: "$_id", rootUpdatedAt: { $first: "$updatedAt" }, // 保留根文档的updatedAt latestEmbedded: { $max: "$embedded" } // 取updatedAt最大的嵌入文档 } }, // 重构为原文档结构 { $project: { _id: 1, updatedAt: "$rootUpdatedAt", embedded: ["$latestEmbedded"] // 将单个文档放回数组 } } ])
方案2:先排序再取首个文档(逻辑更直观)
如果需要明确按updatedAt降序排序后取第一个,可采用此方案:
db.collection.aggregate([ { $match: { embedded: { $exists: true, $ne: [] } } }, { $unwind: "$embedded" }, // 按根文档ID升序、嵌入文档updatedAt降序排序 { $sort: { "_id": 1, "embedded.updatedAt": -1 } }, { $group: { _id: "$_id", rootUpdatedAt: { $first: "$updatedAt" }, latestEmbedded: { $first: "$embedded" } // 取排序后的第一个(最新)文档 } }, { $project: { _id: 1, updatedAt: "$rootUpdatedAt", embedded: ["$latestEmbedded"] } } ])
预期结果
{ _id: "123", updatedAt: ISODate("2023-03-02T14:04:37.925+00:00"), embedded: [ { _id: "789", updatedAt: ISODate("2023-04-10T14:04:37.925+00:00") } ] }
注意事项
- 若多个嵌入文档的
updatedAt完全相同,$max或$first会返回其中一个,具体结果取决于MongoDB内部处理逻辑 - 两个方案均会处理所有符合条件的根文档,无需逐个操作
内容的提问来源于stack exchange,提问作者Srikar
相关产品推荐
相关产品推荐

