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

如何在MongoDB更新或聚合操作中生成唯一的ObjectId?

原因说明

你当前写法里的new ObjectId()是在mongo shell本地执行的,整个更新请求发送到数据库前就已经生成了一个固定的ObjectId值,所以所有匹配到的子文档都会被赋值为同一个_id。

推荐解决方案(MongoDB 4.2及以上版本可用)

使用带聚合管道的更新操作,遍历数组时为每个缺失_id的子文档单独生成新的ObjectId,即可保证唯一性:

db.jobs.updateMany(
  {},
  [
    {
      $set: {
        artifacts: {
          $map: {
            input: "$artifacts",
            in: {
              $mergeObjects: [
                "$$this",
                {
                  _id: {
                    $cond: [
                      { $ne: [{ $type: "$$this._id" }, "missing"] },
                      "$$this._id",
                      new ObjectId()
                    ]
                  }
                }
              ]
            }
          }
        }
      }
    }
  ]
)

低版本兼容方案(适用于所有MongoDB版本)

如果你的数据库版本低于4.2,不支持聚合管道更新,可以用游标遍历文档逐个处理:

db.jobs.find().forEach(job => {
  if (!Array.isArray(job.artifacts)) return
  job.artifacts.forEach(item => {
    if (!item._id) item._id = new ObjectId()
  })
  db.jobs.replaceOne({ _id: job._id }, job)
})

这种方式是逐个处理每个子文档,每个_id都是单独生成的,不会出现重复问题,数据量较大时执行效率会低于批量更新。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:45:02