MongoDB 具有多个 "ON" 条件的聚合查找

MongoDB aggregate lookup with multiple "ON" criteria

我在 MongoDB 中有两个集合,里面有一些数组和嵌套数组,考虑到两个外键,我想查找或其他东西。

集合结构:

股票

{
 merchantIds: ["abc"],
 products: [
  {
   code: "123",
   quantity: 10
  },
  {
   code: "456",
   quantity: 15
  },
  {
   code: "999",
   quantity: 99
  }
 ]
}

订单

{
 id: "123456789",
 items: [
  {
   name: "aaa",
   externalCode: "123",
   quantity: 1,
   options: [
    {
     name: "ccc",
     externalCode: "999",
     quantity: 2,
    }
   ],
  },
  {
   name: "bbb",
   externalCode: "456",
   quantity: 2,
   options: [
    name: "aaa",
    externalCode: "123",
    quantity: 5,
   ]
  },
  {
   name: "ddd",
   externalCode: "789",
   quantity: 2,
   options: []
  }
 ]
}

我想在两个集合之间创建聚合管道以获得此结果:

[
 {
  name: "aaa",
  externalCode: "123"
 },
 {
  name: "bbb",
  externalCode: "456"
 },
 {
  name: "ccc",
  externalCode: "999"
 }
]

我如何在聚合管道中同时考虑 items.externalCodeitems.options.externalCode 并减少到这个结果?

您可以在聚合管道中执行以下操作:

  1. 使用 $map$reduce
  2. 展平 itemsitems.options 数组
  3. 使用 $setUnion
  4. 创建上述结果的联合数组
  5. $lookupstocks collection。在 sub-pipeline 中,指定您的加入条件
  6. $unwind 修剪不匹配的结果
db.orders.aggregate([
  {
    "$match": {
      id: "123456789"
    }
  },
  {
    "$project": {
      items: {
        "$map": {
          "input": "$items",
          "as": "i",
          "in": {
            name: "$$i.name",
            externalCode: "$$i.externalCode"
          }
        }
      },
      options: {
        "$reduce": {
          "input": "$items",
          "initialValue": [],
          "in": {
            "$concatArrays": [
              "$$value",
              {
                "$reduce": {
                  "input": "$$this.options",
                  "initialValue": [],
                  "in": {
                    "$concatArrays": [
                      "$$value",
                      [
                        {
                          name: "$$this.name",
                          externalCode: "$$this.externalCode"
                        }
                      ]
                    ]
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    "$project": {
      union: {
        "$setUnion": [
          "$items",
          "$options"
        ]
      }
    }
  },
  {
    "$unwind": "$union"
  },
  {
    "$lookup": {
      "from": "stocks",
      let: {
        extCode: "$union.externalCode"
      },
      pipeline: [
        {
          $match: {
            merchantIds: "abc"
          }
        },
        {
          "$match": {
            $expr: {
              "$in": [
                "$$extCode",
                "$products.code"
              ]
            }
          }
        }
      ],
      "as": "lookupResult"
    }
  },
  {
    "$unwind": "$lookupResult"
  },
  {
    $project: {
      externalCode: "$union.externalCode",
      name: "$union.name"
    }
  }
])

这里是Mongo playground供您参考。