MongoDB聚合:从嵌套数组生成warehouseStatus新字段
MongoDB聚合:为每个instock元素添加warehouseStatus字段
假设集合文档结构示例
{ "_id": ObjectId("60d21b4667d0d8992e610c85"), "product": "notebook", "instock": [ { "sku": "NB-001", "warehouse": [ { "status": "in_stock", "createdAt": ISODate("2024-01-01T00:00:00Z") }, { "status": "out_of_stock", "createdAt": ISODate("2024-01-05T00:00:00Z") } ] }, { "sku": "NB-002", "warehouse": [ { "status": "backordered", "createdAt": ISODate("2024-01-02T00:00:00Z") }, { "status": "in_stock", "createdAt": ISODate("2024-01-06T00:00:00Z") } ] } ] }
适用MongoDB 5.2+的聚合方案
利用$sortArray直接对数组排序并取最新元素,效率更高:
db.inventory.aggregate([ // 拆分instock数组,逐个处理每个元素 { $unwind: "$instock" }, // 给每个instock添加临时字段,存储排序后的最新warehouse记录 { $addFields: { "instock.latestWarehouse": { $first: { $sortArray: { input: "$instock.warehouse", sortBy: { createdAt: -1 } // 按createdAt降序,最新的排在最前 } } } } }, // 提取最新warehouse的status作为warehouseStatus { $addFields: { "instock.warehouseStatus": "$instock.latestWarehouse.status" } }, // 清理临时字段 { $unset: "instock.latestWarehouse" }, // 将拆分后的instock元素重新组合为数组,同时保留原文档其他顶级字段 { $group: { _id: "$_id", instock: { $push: "$instock" }, product: { $first: "$product" } // 替换为你实际需要保留的顶级字段 } } ])
兼容低版本MongoDB(<5.2)的聚合方案
如果你的MongoDB版本不支持$sortArray,可以用以下方式实现:
db.inventory.aggregate([ // 拆分instock数组 { $unwind: "$instock" }, // 拆分每个instock下的warehouse数组 { $unwind: "$instock.warehouse" }, // 按文档ID、instock元素、createdAt降序排序,确保最新的warehouse排在最前 { $sort: { "_id": 1, "instock.sku": 1, // 用instock的唯一标识字段排序,比如sku "instock.warehouse.createdAt": -1 } }, // 按文档ID和instock唯一标识分组,取第一个(最新的)warehouse的status { $group: { _id: { docId: "$_id", sku: "$instock.sku" }, instock: { $first: "$instock" }, latestStatus: { $first: "$instock.warehouse.status" }, product: { $first: "$product" } // 保留原文档顶级字段 } }, // 添加warehouseStatus字段 { $addFields: { "instock.warehouseStatus": "$latestStatus" } }, // 清理临时字段 { $unset: "latestStatus" }, // 重新组合instock数组 { $group: { _id: "$_id.docId", instock: { $push: "$instock" }, product: { $first: "$product" } } } ])
关键说明
- 如果你需要保留原文档的其他顶级字段(如示例中的
product),必须在$group阶段用$first明确指定,否则这些字段会丢失。 - 低版本方案中,需要用instock元素的唯一标识(如
sku)来分组,确保每个instock元素能正确匹配到最新的warehouse状态。
内容的提问来源于stack exchange,提问作者Dan Fleser
相关产品推荐
相关产品推荐

