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

如何使用Mongoose的$lookup多集合查询获取去重产品库存结果

MongoDB多集合关联计算库存问题解决方案

原代码存在的问题

  • 过早执行$unwind操作:$unwind "$sales"会直接过滤掉没有任何销售记录的产品,导致数据缺失;同时多次$unwind会生成销售记录和批次的笛卡尔积,导致后续求和时重复计算,结果偏差。
  • 字段引用错误:聚合根是products集合,不存在$products._id、$products.description这类字段,直接引用$_id、$description即可获取产品本身的属性。
  • $group阶段语法错误:同一个分组配置里写了两个_id字段,后定义的会覆盖前者,原本按产品属性分组的逻辑完全不生效。
  • 计算逻辑错误:先对单批次库存和单条销量做减法再求和的逻辑错误,正确逻辑应该是先统计该SKU所有批次的总入库量,再统计该SKU的总销量,最后用总入库量减总销量得到库存。

正确的聚合查询代码

db.products.aggregate([
  // 可在此处添加产品过滤条件,无过滤需求可省略该$match阶段
  {
    $lookup: {
      from: "batches",
      localField: "sku",
      foreignField: "sku",
      as: "batches"
    }
  },
  {
    $lookup: {
      from: "sales",
      localField: "sku",
      foreignField: "sku",
      as: "sales"
    }
  },
  {
    $project: {
      description: 1,
      stock: {
        $subtract: [
          // 统计该SKU所有批次的总入库量,无批次则默认返回0
          { $sum: "$batches.units" },
          // 统计该SKU所有的总销量,无销量则默认返回0
          { $sum: "$sales.quantityShipped" }
        ]
      }
    }
  }
])

步骤说明

  • 先用两次$lookup分别关联同一SKU的所有批次记录和销售记录,结果存在对应数组字段中,不需要$unwind拆分。
  • 在$project阶段直接用$sum对数组内的指定字段求和,直接得到总入库量和总销量,再做减法得到最终库存,避免了笛卡尔积导致的计算错误。
  • 自动保留所有产品,无批次时库存为负销量,无销量时库存为总批次入库量,符合通用业务逻辑。

示例数据运行结果

针对你给出的示例数据,运行上述代码后返回结果如下,和预期输出格式完全匹配:

[
  {
    "_id": "对应产品的_id值",
    "description": "A black Shoe",
    "stock": 30
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 12:42:03