简体   繁体   中英

How to identify and process records with MongoBulkWriteException with IsOrdered = false C#

I am trying to insert records using collection.InsertMany with IsOrdered = false.

I have a unique index defined on the collection.

While inserting, I get error as below:

MongoDB.Driver.MongoBulkWriteException`1: 'A bulk write operation resulted in one or more errors.
  E11000 duplicate key error collection: DB.Person index: UniqueIndex dup key: { "John"}
  E11000 duplicate key error collection: DB.Person index: UniqueIndex dup key: { "Smith"}'

For the duplicate records, I want to identify the records which failed, delete the existing records from the database and create it again.

How can we achieve this?

If you set the IsOrdered option you cannot figure out which documents were inserted or not inserted due to the collection may have been reordered for processing.

I've quoted the MongoDB documentation that explains this below ( https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#execution-of-operations )

If ordered is set to false, documents are inserted in an unordered format and may be reordered by mongod to increase performance. Applications should not depend on ordering of inserts if using an unordered insertMany().

However, if you set IsOrdered to true you'll be able to catch a MongoBulkWriteException exception and look at the results.

Here's an example below:

var client = new MongoClient();
var database = client.GetDatabase("test");
var collection = database.GetCollection<Person>("people");
await database.DropCollectionAsync(collection.CollectionNamespace.CollectionName);
await collection.Indexes.CreateOneAsync(new CreateIndexModel<Person>(
    Builders<Person>.IndexKeys.Ascending(person => person.UniqueId), new CreateIndexOptions { Unique = true }
));

await collection.InsertOneAsync(new Person
{
    UniqueId = "dupe",
    Name = Guid.NewGuid().ToString()
});


var data = new[]
{
    new Person
    {
        UniqueId = "new1",
        Name = Guid.NewGuid().ToString()
    },
    new Person
    {
        UniqueId = "dupe",
        Name = Guid.NewGuid().ToString()
    }
};
try
{
    await collection.InsertManyAsync(data, new InsertManyOptions
    {
        IsOrdered = true // This is default and is only specified for verbosity
    });
}
catch (MongoBulkWriteException<Person> ex)
{
    // Fetch the write errors and match them to what we sent in to be inserted
    var failedDocumets = ex.WriteErrors.Select(x => ex.Result.ProcessedRequests[x.Index] as InsertOneModel<Person>)
        .Select(x => x.Document).ToArray();

    Console.WriteLine("Failed Inserts");
    Console.WriteLine(failedDocumets.ToJson()); // [{ "_id" : ObjectId("5ed8ba6995b6e656e4bef2f6"), "UniqueId" : "dupe", "Name" : "a3b10249-35f4-4d72-8f63-b7c756b4ed11" }]
}

public class Person
{
    public ObjectId Id { get; set; }

    public string UniqueId { get; set; }

    public string Name { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM