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

如何通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 14:45:00