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

MongoDB如何在字段不存在时赋值,存在时保留原值

MongoDB 实现更新时仅当tempId不存在才赋值的操作

原始文档

{
    "_id" : ObjectId("6336d94e0330f5d48e44fb0f"),
    "systemId" : "5124301",
    "userId" : "9876543210",
    "tempId" : "123456da87sdafasdf",
    "updatedAt" : ISODate("2022-09-30T12:01:11.714+0000"),
    "receivedAt" : ISODate("2022-04-10T23:15:08.145+0000"),
}

需求说明

更新文档的userId、receivedAt等字段时,仅当tempId字段不存在时为其赋值;若tempId已存在,则保持原值不变。

预期更新结果

场景1:tempId已存在时

更新后tempId保留原值,仅修改userId:

{
    "_id" : ObjectId("6336d94e0330f5d48e44fb0f"),
    "systemId" : "5124301",
    "userId" : "1234567890",
    "tempId" : "123456da87sdafasdf",
    "updatedAt" : ISODate("2022-09-30T12:01:11.714+0000"),
    "receivedAt" : ISODate("2022-04-10T23:15:08.145+0000"),
}

场景2:tempId不存在时

自动为tempId赋值"13qeqrwrqwtqrfsdfweqr",同时修改userId:

{
    "_id" : ObjectId("6336d94e0330f5d48e44fb0f"),
    "systemId" : "5124301",
    "userId" : "1234567890",
    "tempId" : "13qeqrwrqwtqrfsdfweqr",
    "updatedAt" : ISODate("2022-09-30T12:01:11.714+0000"),
    "receivedAt" : ISODate("2022-04-10T23:15:08.145+0000"),
}

错误尝试示例

findOneAndUpdate({
    systemId: "5124301"
},
{
    {
        $set: {
            userId: "1234567890",
            receivedAt : ISODate("2022-04-10T23:15:08.145+0000"),
            tempId: {
                      $exists: then leave it as is, else update it with 13qeqrwrqwtqrfsdfweqr
            }
        }
    }
})

错误原因:$exists是查询条件操作符,不能直接用于字段赋值逻辑,不符合MongoDB更新语法。

正确的findOneAndUpdate语句

db.collection.findOneAndUpdate(
  // 查询条件:匹配指定systemId的文档
  { systemId: "5124301" },
  // 更新逻辑:使用聚合管道实现条件赋值
  [
    {
      $set: {
        userId: "1234567890",
        receivedAt: ISODate("2022-04-10T23:15:08.145Z"),
        // 用$ifNull判断:tempId存在则保留原值,不存在则设置新值
        tempId: { $ifNull: ["$tempId", "13qeqrwrqwtqrfsdfweqr"] }
      }
    }
  ],
  // 可选配置:返回更新后的文档
  { returnNewDocument: true }
)

说明

  • 该方法基于MongoDB 4.2及以上版本的聚合管道更新特性实现
  • $ifNull表达式会自动检查字段:若tempId存在则返回自身值,不存在则返回指定的新值,从而实现"仅当不存在时赋值"的需求
  • $set操作会确保userId和receivedAt字段被正常更新,不受tempId状态影响

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 20:30:49