为什么这个upsert会因重复的id异常而失败?

时间:2017-05-12 21:10:44

标签: mongodb mongodb-.net-driver

这个不时出现。我把操作作为一个upsert完成,但每隔一段时间,服务崩溃,因为它遇到这个错误,我不明白它是如何甚至可能的。我尝试使用SurveyId作为要匹配的键来进行upsert:

await _surveyRepository.DatabaseCollection.UpdateOneAsync(
    Builders<SurveyData>.Filter.Eq(survey => survey.SurveyId, surveyData.SurveyId),
    Builders<SurveyData>.Update
        .Set(survey => survey.SurveyLink, surveyData.SurveyLink)
        .Set(survey => survey.ClientId, surveyData.ClientId)
        .Set(survey => survey.CustomerFirstName, surveyData.CustomerFirstName)
        .Set(survey => survey.CustomerLastName, surveyData.CustomerLastName)
        .Set(survey => survey.SurveyGenerationDateUtc, surveyData.SurveyGenerationDateUtc)
        .Set(survey => survey.PortalUserId, surveyData.PortalUserId)
        .Set(survey => survey.PortalUserFirst, surveyData.PortalUserFirst)
        .Set(survey => survey.PortalUserLast, surveyData.PortalUserLast)
        .Set(survey => survey.Tags, surveyData.Tags),
    new UpdateOptions { IsUpsert = true })
.ConfigureAwait(false);

我偶尔会遇到这个错误:

  

消息:写入操作导致错误。 E11000重复   key error collection:surveys.surveys index:SurveyId dup key:{:   “”}

id是Guid的字符串表示形式,在mongo中设置为唯一。

那么为什么会这样呢?我的理解是,如果找到密钥,它将更新已定义的属性,如果没有,则会插入。这不正确吗?因为,这就是我需要的效果。

C#驱动程序版本是2.4.1.18

2 个答案:

答案 0 :(得分:1)

这是因为根据Jira ticket

  

在使用upsert:true选项进行更新期间,两个(或更多)线程可以使用相同的查询谓词尝试upsert操作,并且在未找到匹配项时,线程将尝试插入新文档。两个插入都将(并且应该)成功,除非第二个插入导致唯一约束违规。

答案 1 :(得分:-1)

  

据我所知,如果找到钥匙,它会更新   定义的属性,如果没有,它将插入。这是不正确的

是的,这就是upsert的作用。新插入的文档将包含标准部分(在您的案例surveyId中)的所有字段以及更新查询的更新修改部分(所有其他指定字段)。
您需要在查询中设置upsert = false。然后它只会更新具有匹配条件的文档,如果找不到匹配项,则更新将失败。