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

MongoDB更新以$开头的字符串字段时字段被删除如何解决

问题原因

你遇到的问题是MongoDB更新管道的字段引用机制导致的:当你给updateOne传入数组类型的第二个参数时,MongoDB会将其识别为更新管道执行,管道内$set的字段值如果以$开头,会被默认解析为对同文档其他字段的引用,而非普通字符串。bcrypt生成的哈希恰好以$2a$/$2b$这类前缀开头,MongoDB找不到对应名称的字段,就会将hash字段赋值为null,最终表现为字段被移除。

解决方案

方案1:改用普通更新语法(最推荐)

如果你的更新逻辑不需要用到管道的复杂计算能力,直接去掉第二个参数的数组包裹,使用普通更新语法即可。普通更新模式下不会解析值内的$为字段引用:

const hash = await bcrypt.hash(password, 10);

// 去掉数组包裹,直接传更新对象
collection.updateOne({ email }, {
  $set: { hash }
});

方案2:管道模式下使用$literal标记字面量

如果你确实需要使用更新管道完成复杂逻辑,可以用$literal操作符包裹哈希值,显式告诉MongoDB该值是普通字面量,不需要解析为字段引用:

const hash = await bcrypt.hash(password, 10);

collection.updateOne({ email }, [
  { $set: { hash: { $literal: hash } } }
]);

两种方案都可以正常存储带$前缀的bcrypt哈希,后续验证密码时直接取出字段调用bcrypt.compare即可,不需要额外转义处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 06:00:01