ReplaceOne抛出重复的键异常

Kun*_*Ren 12 mongodb mongodb-.net-driver

我的应用程序从远程服务器接收数据并调用ReplaceOne插入新文件或用给定密钥替换现有文档Upsert = true.(密钥是匿名的*)代码只在一个线程中运行.

但是,偶尔,应用程序崩溃时出现以下错误:

Unhandled Exception: MongoDB.Driver.MongoWriteException: A write operation resulted in an error.                             
  E11000 duplicate key error collection: ****.orders index: _id_ dup key: { : "****-********-********-************" } ---> MongoDB.Driver.MongoBulkWriteException`1[MongoDB.Bson.BsonDocument]: A bulk write operation resulted in one or more errors.                                                                                                              
  E11000 duplicate key error collection: ****.orders index: _id_ dup key: { : "****-********-********-************" }                                                                                                                  
   at MongoDB.Driver.MongoCollectionImpl`1.BulkWrite(IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken)                                                                                                               
   at MongoDB.Driver.MongoCollectionBase`1.ReplaceOne(FilterDefinition`1 filter, TDocument replacement, UpdateOptions options, CancellationToken cancellationToken)                                                                                       
   --- End of inner exception stack trace ---                                                                                
   at MongoDB.Driver.MongoCollectionBase`1.ReplaceOne(FilterDefinition`1 filter, TDocument replacement, UpdateOptions options, CancellationToken cancellationToken)                                                                                       
   at Dashboard.Backend.AccountMonitor.ProcessOrder(OrderField& order)                                                       
   at Dashboard.Backend.AccountMonitor.OnRtnOrder(Object sender, OrderField& order)                                          
   at XAPI.Callback.XApi._OnRtnOrder(IntPtr ptr1, Int32 size1)                                                               
   at XAPI.Callback.XApi.OnRespone(Byte type, IntPtr pApi1, IntPtr pApi2, Double double1, Double double2, IntPtr ptr1, Int32 size1, IntPtr ptr2, Int32 size2, IntPtr ptr3, Int32 size3)                                                                   
Aborted (core dumped) 
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么它可以当我使用有DUP键ReplaceOneUpsert = true选择?

该应用程序正在以下环境和运行时中工作:

.NET Command Line Tools (1.0.0-preview2-003121)

Product Information:
 Version:            1.0.0-preview2-003121
 Commit SHA-1 hash:  1e9d529bc5

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  16.04
 OS Platform: Linux
 RID:         ubuntu.16.04-x64
Run Code Online (Sandbox Code Playgroud)

并且MongoDB.Driver 2.3.0-rc1.

not*_*est 5

Upsert基于过滤器查询工作。如果过滤查询不匹配,它将尝试插入文档。

如果过滤器查询找到该文档,它将替换该文档。

在您的情况下,它可能以两种方式消失,即插入/更新。请检查数据以分析方案。

插入场景:

如果过滤条件中不存在_id,则由upsert自动创建实际的_id。因此,_id不应创建唯一性问题。如果某些其他字段是唯一索引的一部分,则会产生唯一性问题。

替换方案:

您尝试更新的字段应在其上定义唯一索引。请检查集合及其属性上的索引。

可选的。为true时,replaceOne()之一:如果没有文档与过滤器匹配,则从replace参数插入文档。将与过滤器匹配的文档替换为替换文档。

为避免多次更新,请确保对查询字段进行唯一索引。

默认为false。

如果过滤器或替换文档中未指定_id字段,则MongoDB会将_id字段添加到替换文档中。如果两者都存在_id,则值必须相等。

  • 我的过滤器仅针对“_id”,并且要更新插入/替换的文档具有完全相同的“_id”。 (2认同)

ras*_*had 0

您没有提供足够的信息,但情况可能如下:您从服务器接收数据,replaceOne命令与任何记录不匹配并尝试插入新记录,但文档中可能有一个唯一且已经存在的密钥存在于一个集合中。在尝试更新或插入数据之前,请检查数据并对其进行一些更改。