Как перебрать список в mongodb $ lookup и pipe - PullRequest
1 голос
/ 14 марта 2020

У меня есть две коллекции, т.е. родительские и chilednodes.

 {
    "_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, любая помощь по этому вопросу будет заметна.

1 Ответ

2 голосов
/ 14 марта 2020

Вы были так близко. Ваш parentList является массивом, поэтому, когда вы определяете child_id и activeid внутри $lookup, они также являются массивом.

Если мы добавим $unwind перед $lookup + $group в конце ваш запрос работает как положено.

Попробуйте это:

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"
      }
    }
  }
])

MongoPlayground

...