如何在mongodb$lookup和管道中迭代列表

如何在mongodb$lookup和管道中迭代列表,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我有两个集合,即父节点和子节点 { "_id" : "5e6cd8c1996ddf1c28e14505", "parentList" : [ { "_id" : "5e6c70e8996ddf1c28e14504", "startDate" : "2020-02-25T14:01:58.697Z", "active_id" : "child_vesrion_1", "

我有两个集合,即父节点和子节点

 {
    "_id" : "5e6cd8c1996ddf1c28e14505",
    "parentList" : [
        {
            "_id" : "5e6c70e8996ddf1c28e14504",
            "startDate" : "2020-02-25T14:01:58.697Z",
            "active_id" : "child_vesrion_1",
            "child_id" : "5e5e2cd4e972a95b6c32b5bf30"
        },
        {
            "_id" : "5e6c70e8996ddf1c28e14506",
            "startDate" : "2020-02-25T14:01:58.697Z",
            "active_id" : "child_vesrion_1",
            "child_id" : "5e5e2cd4e972a95b6c32b5bf31"
        }
    ]
}
子节点是

{
    "_id" : "5e5e2cd4e972a95b6c32b5bf31",
    "startDate" : "2020-03-25T14:01:58.697Z",
    "endDate" : null,
    "child_vesrion_1" : {
        "childName" : "test3",
        "createdDate" : "2020-02-25T14:01:58.697Z",
        "text" : "test3 text",
        "type" : "test3 type"
    },
    "child_vesrion_2" : {
        "childName" : "Test4",
        "createdDate" : "2020-02-25T14:01:58.697Z",
        "text" : "test4 text",
        "type" : "test4 type"
    },
    "active" : "child_vesrion_1"
},
{
    "_id" : "5e5e2cd4e972a95b6c32b5bf30",
    "startDate" : "2020-02-25T14:01:58.697Z",
    "endDate" : null,
    "child_vesrion_1" : {
        "childName" : "test1",
        "createdDate" : "2020-02-25T14:01:58.697Z",
        "text" : "test1 text",
        "type" : "test1 type"
    },
    "child_vesrion_2" : {
        "childName" : "test2",
        "createdDate" : "2020-02-25T14:01:58.697Z",
        "text" : "test2 text",
        "type" : "test2 type"
    },
    "active" : "child_vesrion_1"
}
这是我的疑问

db.parent.aggregate([
    { $match: { "_id": "5e6cd8c1996ddf1c28e14505" } },
    {
        $lookup: {
            from: "childnodes",
            let: { "child_id": "$parentList.child_id", "activeid": "$parentList.active_id" },
            pipeline: [
                { $match: { "$expr": { $eq: ["$_id", "$$child_id"] } } },
                {
                    $project: {
                        "child_id": "$_id",
                        "start_date": "$startDate",
                        "current_version_Key": "$active",
                        "active_child_name": {
                            "$reduce": {
                                "input": { "$objectToArray": "$$ROOT" },
                                "initialValue": "",
                                "in": {
                                    "$cond": [{ "$eq": ["$$this.k", "$$activeid"] },
                                        "$$this.v.childName",
                                        "$$value"
                                    ]
                                }
                            }
                        },
                        "text": {
                            "$reduce": {
                                "input": { "$objectToArray": "$$ROOT" },
                                "initialValue": "",
                                "in": {
                                    "$cond": [{ "$eq": ["$$this.k", "$$activeid"] },
                                        "$$this.v.text",
                                        "$$value"
                                    ]
                                }
                            }
                        },
                        "type": {
                            "$reduce": {
                                "input": { "$objectToArray": "$$ROOT" },
                                "initialValue": "",
                                "in": {
                                    "$cond": [{ "$eq": ["$$this.k", "$$activeid"] },
                                        "$$this.v.type",
                                        "$$value"
                                    ]
                                }
                            }
                        }
                    }
                }
            ],
            as: "finalList",
        },
    },
    {
        $project: {
          parentList: 0,
        },
      },
]);
我期待这样的结果

{
  "_id": "5e6cd8c1996ddf1c28e14505",
  "finalList": [
    {
      "child_id": "5e5e2cd4e972a95b6c32b5bf30",
      "start_date": "2020-02-25T14:01:58.697Z",
      "current_version_Key": "child_vesrion_1",
      "active_child_name": "test1",
      "text": "test1 text",
      "type": "test1 type",

    },
    {
      "child_id": "5e5e2cd4e972a95b6c32b5bf31",
      "start_date": "2020-02-25T14:01:58.697Z",
      "current_version_Key": "child_vesrion_1",
      "active_child_name": "test3",
      "text": "test3 text",
      "type": "test3 type",

    }
  ]
}
但我在finalList没有得到任何东西。它正在返回一个空数组

我尝试过不同的方法,但对我没有帮助。我对mongodb有点陌生,这方面的任何帮助都是值得的

你离得太近了。父列表是一个数组,所以在$lookup中定义child_id和activeid时,它们也是数组

如果我们在末尾的$lookup+$组之前添加$unwind,您的查询将按预期工作

试试这个:

db.parent.aggregate([
  {
    $match: {
      "_id": "5e6cd8c1996ddf1c28e14505"
    }
  },
  {
    $unwind: "$parentList"
  },
  {
    $lookup: {
      from: "childnodes",
      let: {
        "child_id": "$parentList.child_id",
        "activeid": "$parentList.active_id"
      },
      pipeline: [
        {
          $match: {
            "$expr": {
              $eq: [
                "$_id",
                "$$child_id"
              ]
            }
          }
        },
        {
          $addFields: {
            child_version: {
              $arrayElemAt: [
                {
                  $filter: {
                    input: {
                      $objectToArray: "$$ROOT"
                    },
                    cond: {
                      $eq: [
                        "$$this.k",
                        "$$activeid"
                      ]
                    }
                  }
                },
                0
              ]
            }
          }
        },
        {
          $project: {
            "_id": 0,
            "child_id": "$_id",
            "start_date": "$startDate",
            "current_version_Key": "$active",
            "active_child_name": "$child_version.v.childName",
            "text": "$child_version.v.text",
            "type": "$child_version.v.type"
          }
        }
      ],
      as: "finalList"
    }
  },
  {
    $unwind: "$finalList"
  },
  {
    $group: {
      _id: "$_id",
      parentList: {
        $push: "$finalList"
      }
    }
  }
])
你是如此接近。父列表是一个数组,所以在$lookup中定义child_id和activeid时,它们也是数组

如果我们在末尾的$lookup+$组之前添加$unwind,您的查询将按预期工作

试试这个:

db.parent.aggregate([
  {
    $match: {
      "_id": "5e6cd8c1996ddf1c28e14505"
    }
  },
  {
    $unwind: "$parentList"
  },
  {
    $lookup: {
      from: "childnodes",
      let: {
        "child_id": "$parentList.child_id",
        "activeid": "$parentList.active_id"
      },
      pipeline: [
        {
          $match: {
            "$expr": {
              $eq: [
                "$_id",
                "$$child_id"
              ]
            }
          }
        },
        {
          $addFields: {
            child_version: {
              $arrayElemAt: [
                {
                  $filter: {
                    input: {
                      $objectToArray: "$$ROOT"
                    },
                    cond: {
                      $eq: [
                        "$$this.k",
                        "$$activeid"
                      ]
                    }
                  }
                },
                0
              ]
            }
          }
        },
        {
          $project: {
            "_id": 0,
            "child_id": "$_id",
            "start_date": "$startDate",
            "current_version_Key": "$active",
            "active_child_name": "$child_version.v.childName",
            "text": "$child_version.v.text",
            "type": "$child_version.v.type"
          }
        }
      ],
      as: "finalList"
    }
  },
  {
    $unwind: "$finalList"
  },
  {
    $group: {
      _id: "$_id",
      parentList: {
        $push: "$finalList"
      }
    }
  }
])

谢谢你的回答@valijon。我正在尝试优化这段代码。我有没有办法优化$reduce方法?假设我需要child table的所有3个值active\u child\u name,type,text@SwagathShatty我已经用优化的代码更新了我的答案。非常感谢:我感谢你的帮助:感谢你的支持@valijon。看起来我们在$lookup下的let在azure cosmos db中不受支持。我正在尝试重写此查询,而不使用let。但它变得越来越复杂。有没有办法不使用let重写此查询?@SwagathShatty try谢谢您的回答@valijon。我正在尝试优化这段代码。我有没有办法优化$reduce方法?假设我需要child table的所有3个值active\u child\u name,type,text@SwagathShatty我已经用优化的代码更新了我的答案。非常感谢:我感谢你的帮助:感谢你的支持@valijon。看起来我们在$lookup下的let在azure cosmos db中不受支持。我正在尝试重写此查询,而不使用let。但它变得越来越复杂。有没有办法不用let重写这个查询?@SwagathShatty try