如何在Mongoose中使用$lookup和子子数组中的外键进行聚合?

3

我正在尝试在我的express-mongo项目中JOIN 3个表格。 我有一个名为Product的表格,就像这样:

Product:

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

我需要对求和后的可用数量进行提取,并从其他两个表中减去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
}]

采购订单销售订单被设计为在同一订单中包含不同的产品。 我正在尝试将这3个表合并以获得以下结果:

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

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

我尝试使用以下方式从Product表开始进行聚合:

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"
            }
        }
        ])

感谢那些尝试帮助我的人!

1个回答

1
您可以尝试:
  • 使用$addFields添加quantity字段,
  • 使用$reduce迭代purchaseorders循环,$reduce迭代项目循环并获取匹配产品的数量,并与reduce的初始值相加
  • 使用$reduce迭代salesorders循环,$reduce迭代项目循环并获取匹配产品的数量,并与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"
                        ]
                      }
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
  }
])

游乐场


你好,感谢您的回复。但是我需要一个唯一的对象数组作为结果,例如 [ { productId: xxx, quantity: xx }, { productId: xxx, quantity: xx }, ... ] - Luca Bog
是的,问题在于一个订单可以包含其他的产品。 - Luca Bog
不行,我不能这样做,因为你的结果与我的预期不同。 - Luca Bog
哦,太好了!非常感谢!你能解释一下所有的步骤吗?为什么你不拆开 unwind? - Luca Bog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接