Reputation: 547
I'm inserting 1000 documents in mongodb 3.6 at once using an unordered bulk via mongodb java api 3.6.1 and the method insertMany(List<Document>)
.
try {
collection.insertMany(docs);
} catch (MongoBulkWriteException e) {
// e is :
// Bulk write operation error on server myserver.com:27011. Write errors: [BulkWriteError{index=0, code=11000, message='E11000 duplicate key error collection: foodb.bar index: bar.id_1 dup key: { : 1 }', details={ }}].
}
Let's say only one document triggered a duplicate key error. All others 999 documents were successfully inserted.
How can I know which document triggered the error ?
Of course when getting the duplicate key error, I could search my list of documents with the bar.id
that was duplicated but it's inconvenient (it means parsing the WriteError message...) and if there is two documents with the same bar.id
in the List<Document>
, it's almost impossible to know which triggered the error without asking the db.
Thanks
Upvotes: 2
Views: 2290
Reputation: 47895
MongoBulkWriteException
contains a List<BulkWriteError>
, each failed write will be represented by an element in this list. Each element in this list contains an index
attribute which is populated with the index of the element in the supplied list of documents.
So, you can use this index
to work out which of the supplied documents failed.
Here's a test case showing this in action:
@Test
public void canBulkWriteAndIdentifySpecificFailedDocuments() throws IOException {
MongoClient mongoClient = new MongoClientFactory().create();
MongoCollection<Document> collection = mongoClient.getDatabase("stackoverflow").getCollection("bulkwrite");
// fresh start for this test case
collection.drop();
Document knownDocument = new Document().append("name", new BsonString("beep"));
collection.insertOne(knownDocument);
collection.createIndex(new BasicDBObject("name", 1), new IndexOptions().unique(true));
int createDuplicateOnIndex = 2;
List<Document> docs = Lists.newArrayList();
for (int i = 0; i < 5; i++) {
if (i == createDuplicateOnIndex) {
// deliberately trigger a duplicate key exception
docs.add(knownDocument);
} else {
docs.add(new Document().append("name", new BsonString("beep" + i)));
}
}
try {
collection.insertMany(docs, new InsertManyOptions().ordered(false));
} catch (MongoBulkWriteException ex) {
assertThat(ex.getWriteResult().getInsertedCount(), is(4));
assertThat(ex.getMessage(), containsString("duplicate key error"));
assertThat(ex.getWriteErrors().size(), is(1));
assertThat(ex.getWriteErrors().get(0).getIndex(), is(createDuplicateOnIndex));
assertThat(ex.getWriteErrors().get(0).getCode(), is(11000));
assertThat(ex.getWriteErrors().get(0).getMessage(), startsWith("E11000 duplicate key error"));
}
}
In this test case we ...
new InsertManyOptions().ordered(false)
for an unordered write), one of which breaches the unique indexMongoBulkWriteException
to be thrown and that this exception reports 4 successful writes and 1 failed write with E11000 duplicate key error
and an index value which clearly shows that this failure is associated with the third document (index == 2
) in the given list.Upvotes: 3