如何在子子数组中使用带有外键的 Mongoose 中的 $lookup 聚合?

How to use aggregate with $lookup in Mongoose with foreign key in sub sub array?

我正在尝试在我的 express-mongo 项目中加入 3 tables。 我有一个 table 名为 Product LIKE this:

Product:

_id:5f92a8dfad47ce1b66d4473b
name:"Freno 1"
createdFrom:5f648f7d642ed7082f5ff91f
category:5f92a00c4637a61a397320a1
description:"Freni di tutti i tipi"
sellingPrice:1050
purchasePrice:350

而且我必须在求和后提取可用数量并从其他 2 table 中减去数量:purchaseorderssalesorders

purchaseorders

_id:5f930c6c6817832c0d5acbb4
items:[
{
_id:5f930c6c6817832c0d5acbb5
product:5f92abaf17ec621c1da4f4f9
quantity:10
purchasingPrice:1500
discount:300
},
{
_id:5f930c6c6817832c0d5acbb6
product:5f92a8dfad47ce1b66d4473b
quantity:7
purchasingPrice:1500
discount:300
}]
salesorders

_id:5f930c6c6817832c0d5acbb4
items:[
{
_id:5f930c6c6817832c0d5acbb5
product:5f92abaf17ec621c1da4f4f9
quantity:3
sellingPrice:1500
discount:300
},
{
_id:5f930c6c6817832c0d5acbb6
product:5f92a8dfad47ce1b66d4473b
quantity:3
sellingPrice:1500
discount:300
}]

Purchaseorderssalesorders 被设计为在同一订单中包含不同的产品。 我试图将这 3 个 tables 组合起来得到这样的结果:

[
{_id: 5f92a8dfad47ce1b66d4473b,
name: "Freno 1",
quantity: 4 },
etc.. with all other products
]

我想对 purchaseorders 中的所有数量求和并减去 salesorders 中的数量总和。

我正在尝试使用从产品 table 开始的聚合,如下所示:

let result = await Product.aggregate([
        {
            $lookup: {
                from: "purchaseorders",
                localField: "_id",
                foreignField: "items.product",
                as: "purchaseorders"
            }
        },
        {
            $lookup: {
                from: "salesorders",
                localField: "_id",
                foreignField: "items.product",
                as: "salesorders"
            }
        },
        {
            $unwind: "$purchaseorders"
        },
        {
            $unwind: "$purchaseorders.items"
        },
        {
            $unwind: "$salesorders"
        },
        {
            $unwind: "$salesorders.items"
        },
        {
            $group: {
                _id: "$_id"
            }
        }
        ])

感谢帮助我的人!!

你可以试试,

  • $addFields 添加 quantity 字段,
  • $reduce 迭代purchaseorders 的循环,$reduce 迭代items 的循环并获取匹配产品的数量和$add 初始值为reduce
  • $reduce 迭代salesorders 的循环,$reduce 迭代items 的循环并获取匹配产品的数量和$add 初始值为reduce
  • $subtract采购订单的数量和销售订单的数量
let result = await Product.aggregate([
  // skipped { $lookup },
  // skipped { $lookup },
  {
    $project: {
      _id: 1,
      name: 1,
      quantity: {
        $subtract: [
          {
            $reduce: {
              input: "$purchaseorders",
              initialValue: 0,
              in: {
                $add: [
                  "$$value",
                  {
                    $reduce: {
                      input: "$$this.items",
                      initialValue: 0,
                      in: {
                        $cond: [
                          { $eq: ["$$this.product", "$_id"] },
                          { $add: ["$$value", "$$this.quantity"] },
                          "$$value"
                        ]
                      }
                    }
                  }
                ]
              }
            }
          },
          {
            $reduce: {
              input: "$salesorders",
              initialValue: 0,
              in: {
                $add: [
                  "$$value",
                  {
                    $reduce: {
                      input: "$$this.items",
                      initialValue: 0,
                      in: {
                        $cond: [
                          { $eq: ["$$this.product", "$_id"] },
                          { $add: ["$$value", "$$this.quantity"] },
                          "$$value"
                        ]
                      }
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
  }
])

Playground