使用 $lookup 将嵌套文档中的值替换为其他集合中的匹配文档

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

我有两个这样的收藏:

// collection Shops
[
  {
    "name": "Shop A",
    "countries": [
      {
        "name": "Germany",
        "cities": [
          {
            "name": "Berlin",
            "districts": [
              {
                "name": "First District",
                "distributor_uid": 123
              },
            ]
          }
        ]
      }
    ]
  }
]

//  Collection Distributors
[
  {
    "uid": 123,
    "name": "Peter",
    "fruits": ["Banana", "Apple"]
  }
]

在聚合中,想要将所有出现的distributor_uid 替换为Distributors 集合中的匹配文档,并获得以下输出:

[
  {
    "name": "Shop A",
    "countries": [
      {
        "name": "Germany",
        "cities": [
          {
            "name": "Berlin",
            "districts": [
              {
                "name": "First District",
                "distributor": {
                  "uid": 123,
                  "name": "Peter",
                  "fruits": ["Banana", "Apple"]
                },
              },
            ]
          }
        ]
      }
    ]
  }
]

我尝试了以下$lookup:

db.shops.aggregate([
  {
    $lookup:
    {
      from: "distributors",
      localField: "countries.cities.districts.distributor_uid",
      foreignField: "uid",
      as: "countries.cities.districts.distributor"
    }
  }
])

不幸的是,这只是将所有匹配的经销商文档放入“countries.cities.districts.distributor”的单个数组中,并且不会单独添加现场经销商。

如何通过将集合商店中的字段 distributioner_uid 替换为集合经销商中的相应文档来实现所需的输出?

感谢您的帮助!

mongodb mongodb-query aggregation-framework
1个回答
0
投票

$lookup
阶段会导致使用数组值创建/覆盖字段。它不会将数据合并到当前字段。

您需要一个

$set
阶段来手动将嵌套元素与匹配元素通过
uid
组合起来。

db.shops.aggregate([
  {
    $lookup: {
      from: "distributors",
      localField: "countries.cities.districts.distributor_uid",
      foreignField: "uid",
      as: "distributors"
    }
  },
  {
    $set: {
      countries: {
        $map: {
          input: "$countries",
          as: "country",
          in: {
            $mergeObjects: [
              "$$country",
              {
                cities: {
                  $map: {
                    input: "$$country.cities",
                    as: "city",
                    in: {
                      $mergeObjects: [
                        "$$city",
                        {
                          districts: {
                            $map: {
                              input: "$$city.districts",
                              as: "district",
                              in: {
                                $mergeObjects: [
                                  "$$district",
                                  {
                                    distributor: {
                                      $first: {
                                        $filter: {
                                          input: "$distributors",
                                          cond: {
                                            $eq: [
                                              "$$this.uid",
                                              "$$district.distributor_uid"
                                            ]
                                          }
                                        }
                                      }
                                    }
                                  }
                                ]
                              }
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $unset: [
      "countries.cities.districts.distributor_uid",
      "countries.cities.districts.distributor._id"
    ]
  }
])

演示@Mongo Playground

© www.soinside.com 2019 - 2024. All rights reserved.