MongoDB updateOne with upsert 失败:重复键

MongoDB updateOne with upsert failed: Duplicate Key

我有一个包含 2 个复合唯一索引、uuid 和 id 的集合。如果集合中有一个文档具有唯一值 uuid 和 id(复合唯一),我想更新一个文档,我在文档中发现 updateOne with upsert=true 可以做到这一点。所以,我使用:

db.collection("messages").updateOne({uuid:this.uuid, id:new_message.id}, {$set: {uuid: this.uuid, ...new_message}}, {upsert:true})

这总是会抛出一个错误,指出有一个文档具有重复的 uuid=xxx 和 id=yyy 值。我查了一下,发现一个 post 说明更新和插入 mongodb upsert 操作时发生数据竞争,所以这总是会发生。还有另一种方法吗?如何正确有效地更新包含 100 万个文档的集合?

编辑:

这道题我给错了代码。代码应该是:

db.collection("messages").updateOne({uuid:this.uuid, key:{id:new_message.key.id}}, {$set: {uuid: this.uuid, ...new_message}}, {upsert:true})

因为你有multi-threading,这是一个常见问题。 mongo 中所有支持的操作都将 运行 纳入此问题,因为它基于您的体系结构。

您可以捕获异常并重试该操作。在这种情况下,其中一个线程将成功。另一个将通过异常处理。这是一个可行的解决方法。

你什么时候排除两个线程同时更新同一个文档?这是一个严重的设计问题。这将改变所需的文档状态。

所以,在尝试之后我发现我应该在查询中使用点符号,我将其更改为:

db.collection("messages").updateOne({uuid:this.uuid, "key.id":new_message.key.id}}, {$set: {uuid: this.uuid, ...new_message}}, {upsert:true})

现在可以使用了。