You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB集合嵌套数组的条件更新查询需求

处理MongoDB嵌套动态键数组的更新需求

原始User集合数据

[
  {
    "_id": "000-0000-0001",
    "Roles": {
      "0000-0000-0011": ["0000-0000-0111", "0000-0000-0112", "0000-0000-3333"],
      "0000-0000-0012": ["0000-0000-0121", "0000-0000-0112"]
    }
  },
  {
    "_id": "000-0000-0002",
    "Roles": {
      "0000-0000-0021": ["0000-0000-0222", "0000-0000-0112"],
      "0000-0000-0022": ["0000-0000-0121", "0000-0000-0112"],
      "0000-0000-0022": ["0000-0000-0121", "0000-0000-0112", "0000-0000-3333"]
    }
  }
]

需求说明

针对Roles对象下的每个动态键(EngagementId)对应的RoleId数组,如果数组同时包含0000-0000-3333和0000-0000-0112,则移除其中的0000-0000-3333。

预期结果

[
  {
    "_id": "000-0000-0001",
    "Roles": {
      "0000-0000-0011": ["0000-0000-0111", "0000-0000-0112"],
      "0000-0000-0012": ["0000-0000-0121", "0000-0000-0112"]
    }
  },
  {
    "_id": "000-0000-0002",
    "Roles": {
      "0000-0000-0021": ["0000-0000-0222", "0000-0000-0112"],
      "0000-0000-0022": ["0000-0000-0121", "0000-0000-0112"],
      "0000-0000-0022": ["0000-0000-0121", "0000-0000-0112"]
    }
  }
]

解决方案

由于Roles的键是动态的(每个文档的EngagementId不固定),无法直接用普通的$pull操作,必须通过聚合管道来遍历处理每个动态键对应的数组:

db.User.updateMany(
  {},
  [
    {
      $set: {
        Roles: {
          $arrayToObject: {
            $map: {
              input: { $objectToArray: "$Roles" },
              as: "roleEntry",
              in: {
                k: "$$roleEntry.k",
                v: {
                  $cond: [
                    {
                      $and: [
                        { $in: ["0000-0000-3333", "$$roleEntry.v"] },
                        { $in: ["0000-0000-0112", "$$roleEntry.v"] }
                      ]
                    },
                    { $pull: ["$$roleEntry.v", "0000-0000-3333"] },
                    "$$roleEntry.v"
                  ]
                }
              }
            }
          }
        }
      }
    }
  ]
)

代码解释

  1. $objectToArray: "$Roles":把Roles对象转换成[{k: "EngagementId", v: ["RoleId1", ...]}]格式的数组,方便遍历处理每个动态键。
  2. $map:遍历转换后的数组,对每个键值对做判断和处理:
    • 用$and和$in判断当前数组是否同时包含两个目标RoleId。
    • 如果满足条件,用$pull移除0000-0000-3333;否则保留原数组。
  3. $arrayToObject:把处理后的键值对数组转回原来的对象结构,赋值给Roles字段。
  4. updateMany({}, [...]):对集合中所有文档执行这个更新操作。

内容的提问来源于stack exchange,提问作者ANURAG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 22:10:48