Upsert操作中来自MongoDB的重复密钥错误

问题描述

在某些情况下,我们会从MongoDB获得E11000 Duplicate key error in BatchWriteOperation。 乍一看,这看起来很奇怪,因为此文档仅使用upserts进行更新。 从概念上讲,哪一种实际上不应允许重复的键出现。

我们碰到了这个问题的描述: https://jira.mongodb.org/browse/SERVER-14322

enter image description here

我们的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上有唯一索引。