MongoDB路径更新冲突报错本地复现失败,求排查方案
MongoDB路径冲突错误复现问题
生产环境中更新MongoDB集合的路径"z"时会触发路径"z"的冲突错误,我尝试在本地复现该错误。
我的集合数据如下:
rs0:PRIMARY> db.test.find(); { "_id" : ObjectId("64050396a27f4d08e8c3a0d4"), "a" : 10, "b" : 4444 } { "_id" : ObjectId("640504d3781e448660488d79"), "a" : 1000, "b" : 4444, "d" : 4444 }
我执行了如下更新语句:
rs0:PRIMARY> db.test.update({"a":1000},{$set:{"a":100}, $set:{"a":900}, $set:{"a":10000}}); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }
该语句在Mongo Shell中执行成功,但根据MongoDB源码测试用例,该操作应该失败,请问我遗漏了什么?
解答
你当前的更新语句写法存在关键问题:MongoDB解析查询时,重复的顶级操作符会被自动合并覆盖。你连续写了三个$set,最终只会保留最后一个$set:{"a":10000},相当于只执行了一次对a字段的赋值操作,自然不会触发路径冲突。
而源码测试用例对应的场景,是在同一个更新操作中同时修改存在父子关系的路径(比如同时设置$set:{"z": 1}和$set:{"z.x": 2}),这种情况下才会触发路径冲突错误——因为修改父路径z和子路径z.x属于互斥操作,MongoDB不允许同时进行。
要复现生产环境中的路径冲突,你需要构造类似这样的更新语句:
rs0:PRIMARY> db.test.update({"a":1000}, {$set:{"z": 1}, $set:{"z.x": 2}});
执行这条语句就会触发预期的路径冲突错误。
内容的提问来源于stack exchange,提问作者Vineel
相关产品推荐
相关产品推荐

