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

MongoDB聚合分组问题:按sucursal合并同producto的kilos值

MongoDB聚合分组问题:合并同分店同产品的重量

原始数据

[
  {
    "sucursal": 1,
    "productos": [
      {
        "producto": 1,
        "kilos": 50
      }
    ]
  },
  {
    "sucursal": 2,
    "productos": [
      {
        "producto": 1,
        "kilos": 30
      },
      {
        "producto": 2,
        "kilos": 50
      }
    ]
  },
  {
    "sucursal": 1,
    "productos": [
      {
        "producto": 1,
        "kilos": 50
      },
      {
        "producto": 2,
        "kilos": 40
      }
    ]
  }
]

期望结果

[
  {
    "sucursal": 1,
    "productos": [
      {
        "producto": 1,
        "kilos": 100
      },
      {
        "producto": 2,
        "kilos": 40
      }
    ]
  },
  {
    "sucursal": 2,
    "productos": [
      {
        "producto": 1,
        "kilos": 30
      },
      {
        "producto": 2,
        "kilos": 50
      }
    ]
  }
]

错误代码

const ordenesTotal = await OrdCompCli.aggregate([
  {
    $match: { fechaEntrega: new Date(fecha), estado: { $gt: 0, $lt: 5 } }
  },
  {
    $unwind: "$productos"
  },
  {
    $group: {
      _id: "$sucursal",
      productos: {
        $addToSet: {
          producto: "$productos.producto",
          totalKilos: { $sum: "$productos.kilos" }
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      sucursal: "$_id",
      productos: 1
    },
  },
])

问题分析

你的代码核心问题是分组层级错误:

  • 直接按sucursal分组后,$sum写在$addToSet内部,只能计算当前单条文档的产品重量,无法跨文档累加同产品的总重量。
  • $addToSet会将每个独立的产品对象(哪怕producto相同)都加入数组,导致同一产品重复出现。

修正后的代码

const ordenesTotal = await OrdCompCli.aggregate([
  // 过滤目标文档
  {
    $match: { fechaEntrega: new Date(fecha), estado: { $gt: 0, $lt: 5 } }
  },
  // 展开产品数组,让每个产品成为独立文档
  {
    $unwind: "$productos"
  },
  // 第一步分组:按「分店+产品」组合累加重量
  {
    $group: {
      _id: {
        sucursal: "$sucursal",
        producto: "$productos.producto"
      },
      totalKilos: { $sum: "$productos.kilos" }
    }
  },
  // 第二步分组:按分店重组产品数组
  {
    $group: {
      _id: "$_id.sucursal",
      productos: {
        $push: {
          producto: "$_id.producto",
          kilos: "$totalKilos"
        }
      }
    }
  },
  // 调整输出字段格式
  {
    $project: {
      _id: 0,
      sucursal: "$_id",
      productos: 1
    }
  }
])

步骤说明

  1. $match:保留原过滤逻辑,只处理指定日期和状态的文档。
  2. $unwind:展开产品数组,将每个产品条目转为独立文档,为后续分组累加做准备。
  3. 第一次$group:用{sucursal, producto}作为分组键,确保同一分店的同一产品被归为一组,通过$sum累加所有对应重量。
  4. 第二次$group:按分店重新分组,用$push将已累加好重量的产品组装为数组。
  5. $project:调整输出结构,将_id映射为sucursal字段,移除原始_id。

内容的提问来源于stack exchange,提问作者Mizrain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:45:28