You need to enable JavaScript to run this app. MongoDB 如何编写含$lookup、$group、$sum的聚合查询实现两集合关联求和
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB 如何编写含$lookup、$group、$sum的聚合查询实现两集合关联求和

核心需求

关联MongoDB的collection1(商品主集合)、collection2(库存流水集合),保留collection1的全部原始记录,按照主从集合的外键关联关系,对collection2的quantity字段做分组求和,无匹配记录时求和值为0,最终输出指定结构的文档。

原尝试方案问题排查

此前采用“先对collection2全量分组求和,再执行$lookup关联collection1”的思路无法得到正确结果,通常是以下几个原因导致:

  • 聚合顺序倒置:先对collection2全量聚合的流程中,后续$lookup关联只会返回能匹配到分组结果的主表文档,比如示例中Product4没有对应库存流水,会直接被过滤,不会出现在最终输出中。
  • 关联条件缺失:如果$lookup阶段没有把主集合的_id值透传到从集合的聚合管道中,会把从集合全量分组的结果直接挂载到每个主文档下,无法做到精准关联,最终求和值完全错位。
  • 结构不匹配:直接将分组结果数组映射为inventoryList字段时,会带上分组阶段生成的多余_id字段,和要求的输出结构不符。
正确实现写法

采用主集合驱动的聚合流程,既保证主集合全量数据不丢失,也能做到精准关联、实时求和,具体代码如下:

db.collection1.aggregate([
  // 带管道的$lookup关联,实时匹配+求和
  {
    $lookup: {
      from: "collection2",
      // 透传主集合的_id值,作为从集合的匹配条件
      let: { currentProductId: "$_id" },
      pipeline: [
        // 仅匹配和当前商品关联的库存记录,避免全量扫描
        { $match: { $expr: { $eq: ["$inventory", "$$currentProductId"] } } },
        // 对匹配到的记录做quantity求和
        {
          $group: {
            _id: "$inventory",
            quantity: { $sum: "$quantity" }
          }
        }
      ],
      as: "tempSumResult"
    }
  },
  // 处理无匹配场景,生成要求的inventoryList结构
  {
    $addFields: {
      inventoryList: {
        $cond: {
          if: { $eq: [{ $size: "$tempSumResult" }, 0] },
          then: [{ quantity: 0 }],
          else: "$tempSumResult"
        }
      }
    }
  },
  // 字段重命名、清理临时字段
  {
    $project: {
      _id1: "$_id",
      name: 1,
      units: 1,
      inventoryList: 1,
      _id: 0
    }
  }
])
实现效果说明

执行上述聚合后,返回的结果完全符合要求:

  • Product1关联3条库存流水,求和20+10+50=80
  • Product2关联2条库存流水,求和4+45=49
  • Product3关联1条库存流水,求和49
  • Product4无匹配库存流水,求和值为0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 08:06:07