Mongodb Join 具有嵌套数组和对象

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

如果我有一个类似于集合 1 中的数据,例如嵌套数组和对象,然后我有另一个包含对象的集合。 我如何加入这两个集合并获得完整对象的输出,其中包含每个单独 id 的 id、全名、其经理和部门。我尝试过展开,但我无法获取每个嵌套管理器名称和 ID,因为我想如果我无法获取其中的每一个,我如何将其与其他集合 ID 结合起来。 我怎样才能加入这些?另外,这可能吗?

--Collection 1 {
        "ïd": 1,
        "name": "Max ",
        "managers": [{
                "ïd": 2,
                "name": "Caroline "
            },
            {
                "ïd": 3,
                "name": "Cecilia ",
                "managers": [{
                        "ïd": 4,
                        "name": "Geraldine ",
                        "managers": [{
                                "ïd": 5,
                                "name": "Ingrid "
                            },
                            {
                                "ïd": 6,
                                "name": "Jacqueline "
                            }
                        ]
                    },
                    {
                        "ïd": 7,
                        "name": "Johannes "
                    }
                ]
            }
        ]
    }

    --Collection 2
        [{
            "ïd": 1,
            "fullName": "Max Born",
            "department": "Management"
        }, {
            "ïd": 2,
            "fullName": "Caroline Herschel",
            "department": "Management"
        }, {
            "ïd": 3,
            "fullName": "Cecilia Payne-Gaposchkin",
            "department": "Management"
        }, {
            "ïd": 4,
            "fullName": "Geraldine Seydoux",
            "department": "Sales"
        }, {
            "ïd": 5,
            "fullName": "Ingrid Daubechies",
            "department": "Sales"
        }, {
            "ïd": 6,
            "fullName": "Jacqueline K. Barton",
            "department": "Sales"
        }, {
            "ïd": 7,
            "fullName": "Johannes Kepler",
            "department": "Application Development"
        }]

我的预期输出是这样的

{
            "ïd": 1,
            "name": "Max ",
            "fullName": "Max Born",
            "department": "Management"
},
{            "ïd": 2,
             "name": "Caroline ",
             "fullName": "Caroline Herschel",
             "department": "Management"
}
..... and so on
arrays mongodb object join mongodb-query
1个回答
1
投票

这是工作代码供您参考。

基本思想是:

  1. 使用
    $lookup
    查找全名和部门
  2. 使用
    $zip
    组合原始的管理者数组和查找到的数组
  3. “展平”组合结果
  4. 对不同层重复步骤1-3

然而,尽管可行,但查询相当复杂,我认为这是过度设计的。我建议您重构集合结构以便于处理。

--编辑

db.person.aggregate([
  {
    "$lookup": {
      "from": "employee",
      "localField": "managers.managers.managers._id",
      "foreignField": "_id",
      "as": "lookup"
    }
  },
  {
    "$addFields": {
      "final": {
        "$zip": {
          inputs: [
            {
              $first: {
                $first: "$managers.managers.managers"
              }
            },
            "$lookup"
          ]
        }
      }
    }
  },
  {
    "$addFields": {
      "final": {
        "$reduce": {
          "input": "$final",
          "initialValue": [],
          "in": {
            "$concatArrays": [
              "$$value",
              [
                {
                  "_id": {
                    "$first": "$$this._id"
                  },
                  "name": {
                    "$last": "$$this.name"
                  },
                  "department": {
                    "$last": "$$this.department"
                  },
                  "fullName": {
                    "$last": "$$this.fullName"
                  }
                }
              ]
            ]
          }
        }
      }
    }
  },
  {
    "$lookup": {
      "from": "employee",
      "localField": "managers.managers._id",
      "foreignField": "_id",
      "as": "lookup"
    }
  },
  {
    "$addFields": {
      "final2": {
        "$zip": {
          inputs: [
            {
              $first: "$managers.managers"
            },
            "$lookup"
          ]
        }
      }
    }
  },
  {
    "$addFields": {
      "final": {
        "$reduce": {
          "input": "$final2",
          "initialValue": "$final",
          "in": {
            "$concatArrays": [
              "$$value",
              [
                {
                  "_id": {
                    "$first": "$$this._id"
                  },
                  "name": {
                    "$last": "$$this.name"
                  },
                  "department": {
                    "$last": "$$this.department"
                  },
                  "fullName": {
                    "$last": "$$this.fullName"
                  }
                }
              ]
            ]
          }
        }
      }
    }
  },
  {
    "$lookup": {
      "from": "employee",
      "localField": "managers._id",
      "foreignField": "_id",
      "as": "lookup"
    }
  },
  {
    "$addFields": {
      "final2": {
        "$zip": {
          inputs: [
            "$managers",
            "$lookup"
          ]
        }
      }
    }
  },
  {
    "$addFields": {
      "managers": {
        "$reduce": {
          "input": "$final2",
          "initialValue": "$final",
          "in": {
            "$concatArrays": [
              "$$value",
              [
                {
                  "_id": {
                    "$first": "$$this._id"
                  },
                  "name": {
                    "$last": "$$this.name"
                  },
                  "department": {
                    "$last": "$$this.department"
                  },
                  "fullName": {
                    "$last": "$$this.fullName"
                  }
                }
              ]
            ]
          }
        }
      }
    }
  },
  {
    "$lookup": {
      "from": "employee",
      "localField": "_id",
      "foreignField": "_id",
      "as": "lookup"
    }
  },
  {
    "$addFields": {
      "final2": {
        "$zip": {
          inputs: [
            [
              "$$ROOT"
            ],
            "$lookup"
          ]
        }
      }
    }
  },
  {
    "$project": {
      "final": {
        "$reduce": {
          "input": "$final2",
          "initialValue": "$managers",
          "in": {
            "$concatArrays": [
              "$$value",
              [
                {
                  "_id": {
                    "$first": "$$this._id"
                  },
                  "name": {
                    "$last": "$$this.name"
                  },
                  "department": {
                    "$last": "$$this.department"
                  },
                  "fullName": {
                    "$last": "$$this.fullName"
                  }
                }
              ]
            ]
          }
        }
      }
    }
  }
])

新的 Mongo 游乐场按照 OP 的要求来压平结果。

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