我的理解是使用upsert更新:对单个文档执行true是一个原子操作,因此当集合没有唯一的索引字段时,这应该永远不会导致重复键错误,特别是不会出现在主_id键上:
Order.update({ _id: order._id }, query, { upsert: true }, cb) // with mongoose
但是这出现在mongod.log中:
2015-03-27T09:39:10.349-0400 I WRITE [conn258236] update xyz.orders
query: { _id: "6353f880-c6a7-4260-809f-98e0af27b9a2" } update: { $set: { ...
} keyUpdates:0 writeConflicts:0 **exception: E11000 duplicate key error dup
key: { : "6353f880-c6a7-4260-809f-98e0af27b9a2" } code:11000** numYields:1
locks:{} 138ms
2015-03-27T09:39:10.349-0400 I COMMAND [conn258236] command xyz.$cmd
command: update { update: "orders", writeConcern: { w: 1 }, ordered: true,
updates: [ { q: { _id: "6353f880-c6a7-4260-809f-98e0af27b9a2" }, u: { $set: {
... } }, multi: false, upsert: true } ] } keyUpdates:0 writeConflicts:0
numYields:0 reslen:235 locks:{} 139ms
以下是db.orders.getIndexes()
的输出:
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "xyz.orders"
},
我们正在使用带有WiredTiger的MongoDB 3.0.0版。
答案 0 :(得分:18)
我担心这是一个持续存在的问题。我遇到了同样的问题,我找到了一张关于此的jira票:
https://jira.mongodb.org/browse/SERVER-14322
有两个更新可能带有upsert:true,导致既没有找到文档,也没有插入与查询谓词的唯一索引违规冲突的新文档。
"解决方案"这里是向客户端添加重试代码。