如何在$lookup 之后反转$unwind 或re-assemble?

How to reverse $unwind or re-assemble after $lookup?

我一直在尝试反转嵌套数组中的 $unwind。拜托,如果你能帮助我,那就太好了。提前致谢。

详情如下:

checklists集合,这个集合有步骤,每个步骤有很多区域,我想通过id查找填充区域。我做到了,但我无法逆转 $unwind.

{
    "steps": [{
        "name": "paso1",
        "description": "paso1",
        "estimated_time": 50,
        "active": true,
        "areas": [{
            "area_id": "60b6e728c44f0365c0d547d6"
        }, {
            "area_id": "60b6e7a2c44f0365c0d547d8"
        }]
    }, {
        "name": "paso2",
        "description": "o",
        "estimated_time": 7,
        "active": true,
        "areas": [{
            "area_id": "60b6e76ac44f0365c0d547d7"
        }]
    }, {
        "name": "paso2",
        "description": "l",
        "estimated_time": 7,
        "active": true,
        "areas": [{
            "area_id": "60b6e728c44f0365c0d547d6"
        }]
    }],
    "name": "prueba",
    "description": "prueba",
    "type": "prueba",
    "active": true,
    "updated_at": {
        "$date": "2021-06-02T23:56:02.232Z"
    },
    "created_at": {
        "$date": "2021-06-01T22:44:57.114Z"
    },
    "__v": 0
}

地区合集

{
    "_id":"60b6e706c44f0365c0d547d5"
    "name": "Development",
    "short_name": "DEV",
    "description": "Development area",
    "updated_at": {
        "$date": "2021-06-02T02:03:50.383Z"
    },
    "created_at": {
        "$date": "2021-06-02T02:03:50.383Z"
    },
    "__v": 0,
    "active": true
}

我的聚合

db.checklists.aggregate([
    {
        "$unwind": "$steps"
    },
    {
        "$unwind": "$steps.areas"
    },
    {
        "$lookup": {
            "from": "areas",
            "let": {
                "area_id": {
                    "$toObjectId": "$steps.areas.area_id"
                }
            },
            "pipeline": [
                {
                    "$match": {
                        "$expr": {
                            "$eq": [
                                "$_id",
                                "$$area_id"
                            ]
                        }
                    }
                }
            ],
            "as": "convertedItems"
        }
    },
    {
        "$group": {
            "_id": "$steps.name",
            "root": {
                "$first": "$$ROOT"
            },
            "items": {
                "$push": {
                    "$mergeObjects": [
                        "$steps.areas",
                        {
                            "$arrayElemAt": [
                                "$convertedItems",
                                0
                            ]
                        }
                    ]
                }
            },
        }
    },
    {
        "$addFields": {
            "values": {
                "$reduce": {
                    "input": "$items",
                    "initialValue": [],
                    "in": {
                        "$concatArrays": [
                            "$$value",
                            {
                                "$cond": [
                                    {
                                        "$in": [
                                            "$$this.area_id",
                                            "$$value.area_id"
                                        ]
                                    },
                                    [],
                                    [
                                        "$$this"
                                    ]
                                ]
                            }
                        ]
                    }
                }
            }
        }
    },
    {
        "$addFields": {
            "root.steps.areas": "$values"
        }
    },
    {
        "$replaceRoot": {
            "newRoot": "$root"
        }
    },
    {
        "$group": {
            "_id": "$_id",
            "root": {
                "$first": "$$ROOT"
            },
            "steps": {
                "$push": "$steps"
            }
        }
    },
    {
        "$addFields": {
            "root.steps": "$steps"
        }
    },
    {
        "$replaceRoot": {
            "newRoot": "$root"
        }
    },
    {
        "$project": {
            "convertedItems": 0
        }
    }
])

我无法形成此输出:

 {
        "steps": [{
            "name": "paso1",
            "description": "paso1",
            "estimated_time": 50,
            "active": true,
            "areas": [{
                "_id": "60b6e728c44f0365c0d547d6",
                "name":"Development",
                ..... //join or lookup
            }, {
                "_id": "60b6e7a2c44f0365c0d547d8",
                "name":"Development",
                ..... //join or lookup
            }]
        }],
        "name": "prueba",
        "description": "prueba",
        "type": "prueba",
        "active": true,
        "updated_at": {
            "$date": "2021-06-02T23:56:02.232Z"
        },
        "created_at": {
            "$date": "2021-06-01T22:44:57.114Z"
        },
        "__v": 0
    }

非常感谢!

  • $unwind解构steps数组
  • $lookup with areas collection pass area_id in let
  • $match 转换为字符串
  • 后检查area_ids中的_id
  • $project 显示必填字段
  • $group by _id 并重建 steps 数组并传递您需要的字段
db.checklists.aggregate([
  { $unwind: "$steps" },
  {
    $lookup: {
      from: "areas",
      let: { area_id: "$steps.areas.area_id" },
      pipeline: [
        {
          $match: {
            $expr: { $in: [{ $toString: "$_id" }, "$$area_id"] }
          }
        },
        { $project: { name: 1 } }
      ],
      as: "steps.areas"
    }
  },
  {
    $group: {
      _id: "$_id",
      steps: { $push: "$steps" },
      name: { $first: "$name" },
      description: { $first: "$description" },
      type: { $first: "$type" },
      active: { $first: "$active" },
      updated_at: { $first: "$updated_at" },
      created_at: { $first: "$created_at" },
      __v: { $first: "$__v" }
    }
  }
])

Playground