在生产环境中,仅仅更新MongoDB集合中的路径“z”就会在路径“z”上产生冲突。
我试图在本地模拟同样的错误。
我有一个这样的收藏。
rs0:PRIMARY> db.test.find();
{ "_id" : ObjectId("64050396a27f4d08e8c3a0d4"), "a" : 10, "b" : 4444 }
{ "_id" : ObjectId("640504d3781e448660488d79"), "a" : 1000, "b" : 4444, "d" : 4444 }
我正在尝试更新它。根据Mongo测试,运行一个更新查询会导致冲突。但是当我从Mongo shell尝试时,它成功了。我不确定我错过了什么。
rs0:PRIMARY> db.test.update({"a":1000},{$set:{"a":100}, $set:{"a":900}, $set:{"a":10000}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }
MongoDB源代码的测试代码参考在这里。根据Mongo测试,它失败了。我错过了什么?
https://github.com/mongodb/mongo/blob/bfebe1d457d4a1bbe2a0b9a1e8421215d016ee54/src/mongo/db/update/update_object_node_test.cpp#L1334
1条答案
按热度按时间l7mqbcuq1#
错误来自带有重复键的
$set
如果新字段的名称与现有字段的名称相同(包括_id),则$set将用指定表达式的值覆盖该字段的现有值。
参考:https://www.mongodb.com/docs/manual/reference/operator/aggregation/set/#mongodb-pipeline-pipe.-set
因此,您只能更改值,而不能更改现有的字段键。而且,您不能在一个查询$集合中使用相同的键。
$set运算符将字段的值替换为指定的值。https://www.mongodb.com/docs/v4.2/reference/method/db.collection.update/#db.collection.update
要成功满足您的要求,您需要使用带有更新操作的
aggregation pipeline
注意:从v4.2开始支持=〉update-documents-with-aggregation-pipeline
代码将是这样的:
MONGO PLAYGROUND