arrays - 如何在 $lookup 之后反转 $unwind 或重新组装?

标签 arrays mongodb nested aggregation-framework 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,区域集合在let中传递area_id
  • $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

关于arrays - 如何在 $lookup 之后反转 $unwind 或重新组装?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67816425/

相关文章:

c++ - 动态数组的排序算法编译器错误

java - 数组中没有重复项

arrays - 在Matlab中保存返回多个变量的函数的返回值

mongodb - 通过配置文件设置将 mongod 作为服务启动

javascript - 如何使用 node.js 将格式化查询传递给 mongodb 中的 findOne()

javascript - 从 MongoDB 返回和应用值有困难

javascript - 如何使用 javascript 在嵌套对象中的特定位置添加子节点

javascript - 具有嵌套函数的函数是否被视为单个函数?

javascript - 将 2 个数组参数传递给 wasm

python - 遍历关于嵌套字典的字典