两个集合的并集未输出预期结果

问题描述 投票:0回答:1

我使用的mongo版本为v5.0.19

我有 2 个集合,其中的数据如下:

集合 1 - external_S_P_FLAT_main_api:

[
    {
      "_id": {
        "$oid": "656497ff4f6a4c11e61b865e"
      },
      "data.pricing.material": "TG11",
      "data.pricing.controlling_area": "AJ00",
      "data.pricing.cost_center": "DE000001"
    },
    {
      "_id": {
        "$oid": "656497ff4f6a4c11e61b865f"
      },
      "data.pricing.material": "TG12",
      "data.pricing.controlling_area": "AJ00"
    },
    {
      "_id": {
        "$oid": "656497ff4f6a4c11e61b8660"
      },
      "data.pricing.material": "TG14",
      "data.pricing.controlling_area": "AJ00",
      "data.pricing.cost_center": "DE000003"
    },
    {
      "_id": {
        "$oid": "656497ff4f6a4c11e61b8661"
      },
      "data.pricing.material": "TG2341",
      "data.pricing.controlling_area": "AJ00"
    }
  ]

集合 2 - external_S_C_FLAT_main_api:

[
    {
      "_id": {
        "$oid": "656498004f6a4c11e61b8662"
      },
      "data.costcenter.controlling_area": "AJ00",
      "data.costcenter.cost_center": "DE000001",
      "data.costcenter.company_code": "DE00",
      "data.costcenter.hierarchy_area": "AJ00",
      "data.costcenter.long_description": "CC DE000001 - 3rd"
    },
    {
      "_id": {
        "$oid": "656498004f6a4c11e61b8663"
      },
      "data.costcenter.controlling_area": "AJ00",
      "data.costcenter.cost_center": "DE000003",
      "data.costcenter.company_code": "DE00",
      "data.costcenter.hierarchy_area": "AJ00",
      "data.costcenter.long_description": "CC DE000003 - 1st"
    },
    {
      "_id": {
        "$oid": "656498004f6a4c11e61b8610"
      },
      "data.costcenter.controlling_area": "AJ00",
      "data.costcenter.cost_center": "DE000005",
      "data.costcenter.company_code": "DE00",
      "data.costcenter.hierarchy_area": "AJ00",
      "data.costcenter.long_description": "CC DE000005 - 5th"
    }
  ]

我正在尝试将以下查询与 join 进行联合

db.external_S_P_FLAT_main_api.aggregate([
    {
      "$addFields": {
        "external_S_P_FLAT_main_api_data.pricing.cost_center": "$data.pricing.cost_center"
      }
    },
    {
      "$lookup": {
        from: "external_S_C_FLAT_main_api",
        let: {
          let_data__pricing__cost_center: {
            "$getField": "data.pricing.cost_center"
          }
        },
        pipeline: [
          {
            "$match": {
              "$expr": {
                "$and": [
                  {
                    "$eq": [
                      {
                        "$getField": "data.costcenter.cost_center"
                      },
                      "$$let_data__pricing__cost_center"
                    ]
                  }
                ]
              }
            }
          }
        ],
        as: "from_external_S_C_FLAT_main_api"
      }
    },
    {
      "$unwind": {
        path: "$from_external_S_C_FLAT_main_api",
        preserveNullAndEmptyArrays: true
      }
    },
    {
      "$replaceRoot": {
        newRoot: {
          "$mergeObjects": [
            "$from_external_S_C_FLAT_main_api",
            "$$ROOT"
          ]
        }
      }
    },
    {
      $unionWith: {
        coll: "external_S_C_FLAT_main_api",
        pipeline: [
          {
            "$match": {
              "$expr": {
                "$and": [
                  {
                    "$ne": [
                      {
                        "$getField": "data.costcenter.cost_center"
                      },
                      false
                    ]
                  }
                ]
              }
            }
          },
          {
            $project: {
              _id: 0
            }
          }
        ]
      }
    },
    {
      "$project": {
        _id: 0,
        "external_S_P_FLAT_main_api_data.pricing.controlling_area": 0,
        "external_S_P_FLAT_main_api_data.pricing.cost_center": 0,
        external_S_P_FLAT_main_api_IS_INVALID: 0,
        external_S_P_FLAT_main_api_USER_ID: 0,
        from_external_S_C_FLAT_main_api: 0
      }
    }
  ])

我得到的结果如下:

[
    {
      "data.costcenter.company_code": "DE00",
      "data.costcenter.controlling_area": "AJ00",
      "data.costcenter.cost_center": "DE000001",
      "data.costcenter.hierarchy_area": "AJ00",
      "data.costcenter.long_description": "CC DE000001 - 3rd",
      "data.pricing.controlling_area": "AJ00",
      "data.pricing.cost_center": "DE000001",
      "data.pricing.material": "TG11",
      "external_S_P_FLAT_main_api_data": {
        "pricing": {}
      }
    },
    {
      "data.pricing.controlling_area": "AJ00",
      "data.pricing.material": "TG12",
      "external_S_P_FLAT_main_api_data": {
        "pricing": {}
      }
    },
    {
      "data.costcenter.company_code": "DE00",
      "data.costcenter.controlling_area": "AJ00",
      "data.costcenter.cost_center": "DE000003",
      "data.costcenter.hierarchy_area": "AJ00",
      "data.costcenter.long_description": "CC DE000003 - 1st",
      "data.pricing.controlling_area": "AJ00",
      "data.pricing.cost_center": "DE000003",
      "data.pricing.material": "TG14",
      "external_S_P_FLAT_main_api_data": {
        "pricing": {}
      }
    },
    {
      "data.pricing.controlling_area": "AJ00",
      "data.pricing.material": "TG2341",
      "external_S_P_FLAT_main_api_data": {
        "pricing": {}
      }
    },
    {
      "data.costcenter.company_code": "DE00",
      "data.costcenter.controlling_area": "AJ00",
      "data.costcenter.cost_center": "DE000001",
      "data.costcenter.hierarchy_area": "AJ00",
      "data.costcenter.long_description": "CC DE000001 - 3rd"
    },
    {
      "data.costcenter.company_code": "DE00",
      "data.costcenter.controlling_area": "AJ00",
      "data.costcenter.cost_center": "DE000003",
      "data.costcenter.hierarchy_area": "AJ00",
      "data.costcenter.long_description": "CC DE000003 - 1st"
    },
    {
      "data.costcenter.company_code": "DE00",
      "data.costcenter.controlling_area": "AJ00",
      "data.costcenter.cost_center": "DE000005",
      "data.costcenter.hierarchy_area": "AJ00",
      "data.costcenter.long_description": "CC DE000005 - 5th"
    }
  ]

我想要的预期结果如下,其中集合 2 中的匹配记录 ("data.costcenter.long_description": "CC DE000001 - 3rd", & "data.costcenter.long_description": "CC DE000003 - 1st")

不应再次包含在 unon 结果中。

因此预期结果如下:

[
    {
      "data.costcenter.company_code": "DE00",
      "data.costcenter.controlling_area": "AJ00",
      "data.costcenter.cost_center": "DE000001",
      "data.costcenter.hierarchy_area": "AJ00",
      "data.costcenter.long_description": "CC DE000001 - 3rd",
      "data.pricing.controlling_area": "AJ00",
      "data.pricing.cost_center": "DE000001",
      "data.pricing.material": "TG11",
      "external_S_P_FLAT_main_api_data": {
        "pricing": {}
      }
    },
    {
      "data.pricing.controlling_area": "AJ00",
      "data.pricing.material": "TG12",
      "external_S_P_FLAT_main_api_data": {
        "pricing": {}
      }
    },
    {
      "data.costcenter.company_code": "DE00",
      "data.costcenter.controlling_area": "AJ00",
      "data.costcenter.cost_center": "DE000003",
      "data.costcenter.hierarchy_area": "AJ00",
      "data.costcenter.long_description": "CC DE000003 - 1st",
      "data.pricing.controlling_area": "AJ00",
      "data.pricing.cost_center": "DE000003",
      "data.pricing.material": "TG14",
      "external_S_P_FLAT_main_api_data": {
        "pricing": {}
      }
    },
    {
      "data.pricing.controlling_area": "AJ00",
      "data.pricing.material": "TG2341",
      "external_S_P_FLAT_main_api_data": {
        "pricing": {}
      }
    },
    {
      "data.costcenter.company_code": "DE00",
      "data.costcenter.controlling_area": "AJ00",
      "data.costcenter.cost_center": "DE000005",
      "data.costcenter.hierarchy_area": "AJ00",
      "data.costcenter.long_description": "CC DE000005 - 5th"
    }
  ]

我已经在操场上尝试了上述查询https://mongoplayground.net/p/cKxLEgcD2bj

I have tried the below query. In that, I can see the output but need to get the array which is in comparison with 

db.external_S_P_FLAT_main_api.aggregate([
  {
    "$addFields": {
      "external_S_P_FLAT_main_api_data.pricing.cost_center": "$data.pricing.cost_center"
    }
  },
  {
    "$lookup": {
      from: "external_S_C_FLAT_main_api",
      let: {
        let_data__pricing__cost_center: {
          "$getField": "data.pricing.cost_center"
        }
      },
      pipeline: [
        {
          "$match": {
            "$expr": {
              "$and": [
                {
                  "$eq": [
                    {
                      "$getField": "data.costcenter.cost_center"
                    },
                    "$$let_data__pricing__cost_center"
                  ]
                }
              ]
            }
          }
        }
      ],
      as: "from_external_S_C_FLAT_main_api"
    }
  },
  //{
  {
    "$unwind": {
      path: "$from_external_S_C_FLAT_main_api",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    "$replaceRoot": {
      newRoot: {
        "$mergeObjects": [
          "$from_external_S_C_FLAT_main_api",
          "$$ROOT"
        ]
      }
    }
  },
  {
    $unionWith: {
      coll: "external_S_C_FLAT_main_api",
      pipeline: [
        {
          "$match": {
            "$expr": {
              "$not": [
                {
                  "$in": [
                    {
                      "$getField": "data.costcenter.cost_center"
                    },
                    [
                      "DE000001",
                      "DE000003"
                    ]
                  ]
                }
              ]
            }
          }
        },
        {
          $project: {
            _id: 0
          }
        }
      ]
    }
  },
  {
    "$project": {
      _id: 0,
      "external_S_P_FLAT_main_api_data.pricing.controlling_area": 0,
      "external_S_P_FLAT_main_api_data.pricing.cost_center": 0,
      external_S_P_FLAT_main_api_IS_INVALID: 0,
      external_S_P_FLAT_main_api_USER_ID: 0,
      from_external_S_C_FLAT_main_api: 0
    }
  }
])


I want this array  ["DE000001",  "DE000003"] to be prepared in the previous stage and passed on to the next stage.

Can anyone help me with this
mongodb aggregation-framework union
1个回答
0
投票
Below is the expected query

`
db.external_S_P_FLAT_main_api.aggregate([
  {
    $unionWith: {
      coll: "external_S_C_FLAT_main_api"
    }
  },
  {
    "$lookup": {
      from: "external_S_C_FLAT_main_api",
      let: {
        let_data__pricing__cost_center: {
          "$getField": "data.pricing.cost_center"
        }
      },
      pipeline: [
        {
          "$match": {
            "$expr": {
              "$and": [
                {
                  "$eq": [
                    {
                      "$getField": "data.costcenter.cost_center"
                    },
                    "$$let_data__pricing__cost_center"
                  ]
                }
              ]
            }
          }
        }
      ],
      as: "from_external_S_C_FLAT_main_api"
    }
  },
  {
    "$addFields": {
      "otherId": {
        "$cond": [
          {
            "$eq": [
              {
                $getField: "from_external_S_C_FLAT_main_api"
              },
              []
            ]
          },
          {
            "$toString": "$_id"
          },
          {
            "$toString": {
              $arrayElemAt: [
                "$from_external_S_C_FLAT_main_api._id",
                0
              ]
            }
          },
        ]
      }
    }
  },
  {
    "$unwind": {
      path: "$from_external_S_C_FLAT_main_api",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    "$replaceRoot": {
      newRoot: {
        "$mergeObjects": [
          "$from_external_S_C_FLAT_main_api",
          "$$ROOT"
        ]
      }
    }
  },
  {
    "$lookup": {
      from: "external_S_P_FLAT_main_api",
      let: {
        let_data__costcenter__cost_center: {
          "$getField": "data.costcenter.cost_center"
        }
      },
      pipeline: [
        {
          "$match": {
            "$expr": {
              "$and": [
                {
                  "$eq": [
                    {
                      "$getField": "data.pricing.cost_center"
                    },
                    "$$let_data__costcenter__cost_center"
                  ]
                }
              ]
            }
          }
        }
      ],
      as: "from_external_S_P_FLAT_main_api"
    }
  },
  {
    $group: {
      _id: "$otherId",
      duplicates: {
        $push: "$$ROOT"
      }
    }
  },
  {
    $project: {
      result: {
        $arrayElemAt: [
          "$duplicates",
          0
        ]
      }
    }
  },
  {
    "$unwind": {
      path: "$result",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    "$replaceRoot": {
      newRoot: {
        "$mergeObjects": [
          "$result",
          "$$ROOT"
        ]
      }
    }
  },
  {
    "$project": {
      _id: 0,
      "external_S_P_FLAT_main_api_data.pricing.controlling_area": 0,
      "external_S_P_FLAT_main_api_data.pricing.cost_center": 0,
      external_S_P_FLAT_main_api_IS_INVALID: 0,
      external_S_P_FLAT_main_api_USER_ID: 0,
      from_external_S_C_FLAT_main_api: 0,
      from_external_S_P_FLAT_main_api: 0,
      result: 0,
      otherId: 0
    }
  }`enter code here`
])
`
© www.soinside.com 2019 - 2024. All rights reserved.