如何通过MongoDB聚合操作将prevSold.price提升至history对象同层级
问题原因分析
你的现有聚合语句存在多个逻辑错误,导致返回空数组且结构不符合预期:
$unwind只能作用于数组类型字段,你传入的$history.prevSold是对象不是数组,这一步执行后会直接过滤所有匹配数据- 字段赋值路径错误:你要修改的是
history数组元素下的prevSold字段,现有代码路径完全不匹配 $replaceRoot操作直接替换了文档根节点,就算有匹配数据也会丢失所有上层字段,和你要的返回结构完全不符
解决方案
推荐使用$map直接遍历处理history数组,不需要拆分数组再重组,性能更高,实现更简洁:
const slug = req.params.slug ProductPrice.aggregate([ // 筛选匹配productId的文档,和原find逻辑一致 { $match: { productId: slug } }, // 直接修改history数组内的字段 { $addFields: { history: { $map: { input: "$history", as: "historyItem", in: { // 保留history元素的所有原有字段 $mergeObjects: [ "$$historyItem", // 把prevSold字段替换为内部的price值 { prevSold: "$$historyItem.prevSold.price" } ] } } } } } ]).exec((err, data) => { if (err){ return res.status(400).json({ error: errorHandler(err) }) } res.json(data) })
如果你确实需要用$unwind拆分数组的方式实现(性能更低,不推荐),参考写法如下:
ProductPrice.aggregate([ { $match: { productId: slug } }, // 拆分history数组为单条文档 { $unwind: "$history" }, // 修改history元素下的prevSold字段 { $addFields: { "history.prevSold": "$history.prevSold.price" } }, // 按原文档_id分组,重新拼接history数组,同时保留上层字段 { $group: { _id: "$_id", productId: { $first: "$productId" }, createdAt: { $first: "$createdAt" }, history: { $push: "$history" } } } ])
内容的提问来源于stack exchange,提问作者alienbuild
相关产品推荐
相关产品推荐

