如何通过匹配 mongodb 中的 id 来合并数组字段?

bg_*_*g_k 4 mongodb

假设我有两个字段member并且userData在同一个集合中,如下所示。

{
    member: [
    { _id: ObjectId("60ff03a462256b70fdb979dc"), role: "admin" },
    { _id: ObjectId("60ff03a462256b70fdb97932"), role: "member" },
    { _id: ObjectId("60ff03a462256b70fdb97995"), role: "member" },
  ],

  userData: [
    {
      _id: ObjectId("60ff03a462256b70fdb979dc"),
      name: "Kevin",
      email: "kevin@mail.com",
      ...
    },
    {
      _id: ObjectId("60ff03a462256b70fdb97932"),
      name: "Andrew"
      email: "andrew@mail.com",
      ...
    },
    {
      _id: ObjectId("60ff03a462256b70fdb97995"),
      name: "Jessica",
      email: "jessica@mail.com",
      ...
    },
    ....
  ]
}
Run Code Online (Sandbox Code Playgroud)

如何通过它们合并两个字段(本质上插入memberuserData_id以填充此结果?

userWithRole: [
    {
      _id: ObjectId("60ff03a462256b70fdb979dc"),
      name: "Kevin",
      email: "kevin@mail.com",
      role: "admin"
      ... // all other user data
    }
Run Code Online (Sandbox Code Playgroud)

Tak*_*kis 7

询问

  • 映射每个成员userData
  • 通过过滤member数组找到他的角色
  • 合并对象以添加角色

测试代码在这里

*query 假设您的示例数据是 1 个包含 2 个数组字段的文档。

*下面是聚合,如果您想要更新,您可以通过使用管道进行更新来使用相同的代码,例如update({},[...pipelineBellow..])

db.collection.aggregate([
  {
    "$project": {
      "userWithRole": {
        "$map": {
          "input": "$userData",
          "in": {
            "$let": {
              "vars": {
                "m": {
                  "$arrayElemAt": [
                    {
                      "$filter": {
                        "input": "$member",
                        "cond": {
                          "$eq": [
                            "$$mb._id",
                            "$$this._id"
                          ]
                        },
                        "as": "mb"
                      }
                    },
                    0
                  ]
                }
              },
              "in": {
                "$mergeObjects": [
                  "$$this",
                  {
                    "role": "$$m.role"
                  }
                ]
              }
            }
          }
        }
      }
    }
  }
])
Run Code Online (Sandbox Code Playgroud)