问题描述
在某些情况下,我们会从MongoDB获得E11000 Duplicate key error in BatchWriteOperation
。
乍一看,这看起来很奇怪,因为此文档仅使用upserts进行更新。
从概念上讲,哪一种实际上不应允许重复的键出现。
我们碰到了这个问题的描述: https://jira.mongodb.org/browse/SERVER-14322
我们的Upsert表达式如下(C#)
var l = await _pids.ReplaceOneAsync(x => x.Id == id && x.LockedBy == null,updatedDocument,new ReplaceOptions
{
IsUpsert = true
}
);
Id
是文档的常规_id
,而LockedBy
是文档的未索引属性。
我们之所以会在这里得到重复的键错误,是因为更新的find部分中的谓词包含多个道具吗?
我们当然可以对此进行重试。但是我们非常想知道为什么会得到这种情况,在这种情况下,以上哪些规则适用于我们?
解决方法
如果没有找到匹配的内容,ReplaceOneAsync将尝试对文档进行增补。
如果已经存在具有匹配_id的文档,但是该文档已被锁定,则将不存在匹配的文档,因此将尝试进行upsert。
此upsert将失败(应如此),因为已经有一个具有_id值的文档,并且_id上有唯一索引。