mongodb 更新聚合管道中的 Arrayfilter 等价物

Arrayfilter equivalent in mongodb update aggregation pipeline

我有以下数据结构:

[
  {
    "_id": {
      "$oid": "6295d353fccb2f44c3868f9a"
    },
    "name": "test",
    "managerid": {
      "$oid": "6295d353fccb2f44c3868f99"
    },
    "teachers": [],
    "employees": [
      {
        "employeeid": {
          "$oid": "6295d353fccb2f44c3868f99"
        },
        "firstname": "jean",
        "lastname": "charles",
        "tag": 4595,
        "status": 1
      }
    ],
    "groups": [
      {
        "groupid": {
          "$oid": "6295fa2191ae50ba47e9d25c"
        },
        "groupname": "mongroupe",
        "employees": [],
        "permissions": []
      },
      {
        "groupid": {
          "$oid": "6295fa2191ae50ba47e9d25d"
        },
        "groupname": "mygroup",
        "employees": [],
        "permissions": []
      }
    ]
  }
]

我想将员工对象添加到一个组中。 objective 是为了达到这样的目的:

[
  {
    "_id": {
      "$oid": "6295d353fccb2f44c3868f9a"
    },
    "name": "test",
    "managerid": {
      "$oid": "6295d353fccb2f44c3868f99"
    },
    "teachers": [],
    "employees": [
      {
        "employeeid": {
          "$oid": "6295d353fccb2f44c3868f99"
        },
        "firstname": "jean",
        "lastname": "charles",
        "tag": 4595,
        "status": 1
      }
    ],
    "groups": [
      {
        "groupid": {
          "$oid": "6295fa2191ae50ba47e9d25c"
        },
        "groupname": "mongroupe",
        "employees": [
          {
            "employeeid": {
              "$oid": "6295d353fccb2f44c3868f99"
            },
            "firstname": "jean",
            "lastname": "charles"
          }
        ],
        "permissions": []
      },
      {
        "groupid": {
          "$oid": "6295fa2191ae50ba47e9d25d"
        },
        "groupname": "mygroup",
        "employees": [],
        "permissions": []
      }
    ]
  }
]

这样员工也被嵌入到组对象中。使用以下代码(基于此答案)这将非常容易:

db.collection.update({
  "_id": {
    "$oid": "6295d353fccb2f44c3868f9a",
  },
  "groups.groupid": {
    "$oid": "6295fa2191ae50ba47e9d25c"
  }
},
{
  "$set": {
    "groups.$.employees": {
      "$concatArrays": [
        "$groups.employees",
        {
          "$filter": {
            "input": [
              {
                "employeeid": {
                  "$oid": "6295d353fccb2f44c3868f99"
                }
              }
            ],
            "cond": {
              "$not": {
                "$in": [
                  "$$this.employeeid",
                  "$groups.$.employees.employeeid"
                ]
              }
            }
          }
        }
      ]
    }
  }
})

但问题是聚合管道不能与位置运算符一起工作field.$.otherfield,也不能与数组过滤器一起工作。

因此我无法 select 正确的组("groups.groupid": {"$oid": "6295fa2191ae50ba47e9d25c"} 过滤器)

有人知道该怎么办吗?我对聚合管道还很陌生……这是相关的操场:https://mongoplayground.net/p/8Kgftb2oBpV

您可以使用聚合管道执行以下操作:

  1. $match 符合您的标准
  2. $unwindgroups 级别
  3. $addFields 并使用 $filter
  4. 处理逻辑
  5. $group改造展开的结果
  6. $merge执行更新回集合
db.collection.aggregate([
  {
    $match: {
      "_id": {
        "$oid": "6295d353fccb2f44c3868f9a"
      },
      "groups.groupid": {
        "$oid": "6295fa2191ae50ba47e9d25c"
      }
    }
  },
  {
    "$unwind": {
      path: "$groups",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    "$addFields": {
      "groups.employees": {
        "$cond": {
          "if": {
            $eq: [
              "$groups.groupid",
              ObjectId("6295fa2191ae50ba47e9d25c")
            ]
          },
          "then": {
            "$reduce": {
              "input": "$groups.employees",
              "initialValue": [
                {
                  "employeeid": {
                    "$oid": "6295d353fccb2f44c3868f99"
                  }
                }
              ],
              "in": {
                "$cond": {
                  "if": {
                    "$in": [
                      "$$this.employeeid",
                      "$$value.employeeid"
                    ]
                  },
                  "then": "$$value",
                  "else": {
                    "$concatArrays": [
                      "$$value",
                      [
                        "$$this"
                      ]
                    ]
                  }
                }
              }
            }
          },
          "else": "$groups.employees"
        }
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      employees: {
        $first: "$employees"
      },
      groups: {
        $push: "$groups"
      },
      "managerid": {
        $first: "$managerid"
      },
      "name": {
        $first: "$name"
      },
      "teachers": {
        $first: "$teachers"
      }
    }
  },
  {
    "$merge": {
      "into": "collection",
      "on": "_id",
      "whenMatched": "replace"
    }
  }
])

这里是Mongo Playground供您参考。