Node.js MongoDB报错:更新操作文档必须包含原子操作符
你明明已经用了$set操作符却还是碰到这个报错,确实挺闹心的。我来帮你梳理几个大概率的原因和排查方向:
传递给updateOne的newvalues可能被意外修改了
你打印的newvalues是正确的,但要留意:这个打印是不是在调用updateOne的前一刻做的?有时候我们打印变量后,中间可能有其他逻辑(比如对象赋值、深拷贝、第三方工具处理)悄悄修改了对象结构,导致实际传给updateOne的newvalues已经丢失了$set。建议你在调用updateOne的紧前一行再打印一次newvalues,确保传递的内容和你预期的完全一致:
console.log('执行update前的newvalues:', JSON.stringify(newvalues)); db.get().collection('users').updateOne(query, newvalues, function (err, result) { cb(err,result) });变量传递顺序搞反了
虽然你的代码里写的是updateOne(query, newvalues),但有没有可能实际调用时参数顺序错了?比如不小心把newvalues放到了query的位置,query放到了update文档的位置?这种情况下也会触发报错,因为查询条件不符合原子操作符的格式要求。框架/工具的自动转换“搞破坏”
如果你是在Node.js框架(比如Mongoose)里使用,或者用到了数据处理中间件,有可能这些工具会自动解析或转换你的update文档,把带$前缀的$set当成非法字段给移除了。可以排查下有没有这类自动过滤字段的逻辑。用字面量测试排除变量问题
你可以尝试把update文档直接写死在updateOne调用里,看看能不能正常执行:db.get().collection('users').updateOne( { username: 'macarra' }, { $set: {name: "Mojo Picon",email: "mako@gmail.es"} }, function (err, result) { cb(err,result) } );如果这样能成功运行,那基本可以确定是你的
newvalues变量在传递过程中被修改了,顺着变量的流转路径排查修改逻辑就好。
内容的提问来源于stack exchange,提问作者user7056422

