MongoDB Java: 如何获取写入错误文件?
MongoDB Java: how to get write error document?
我通过 mongodb java api 3.6.1 和方法 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={ }}].
}
假设只有一个文档触发了重复键错误。所有其他 999 个文档已成功插入。
我如何知道哪个文档触发了错误?
当然,当出现重复键错误时,我可以用重复的 bar.id
搜索我的文档列表,但这很不方便(这意味着解析 WriteError 消息...),如果有两个List<Document>
中具有相同 bar.id
的文档,如果不询问数据库,几乎不可能知道是哪个触发了错误。
谢谢
MongoBulkWriteException
包含一个List<BulkWriteError>
,每次失败的写入将由这个列表中的一个元素表示。此列表中的每个元素都包含一个 index
属性,该属性由提供的文档列表中的元素索引填充。
因此,您可以使用此 index
来找出哪些提供的文档失败了。
这里有一个测试用例,展示了这一点:
@Test
public void canBulkWriteAndIdentifySpecificFailedDocuments() throws IOException {
MongoClient mongoClient = new MongoClientFactory().create();
MongoCollection<Document> collection = mongoClient.getDatabase("Whosebug").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"));
}
}
在这个测试用例中我们...
- 写文档
- 在目标集合上创建唯一索引
- 写入文档集合(使用
new InsertManyOptions().ordered(false)
进行无序写入),其中一个违反了唯一索引
- 断言批量插入导致抛出
MongoBulkWriteException
并且此异常报告 4 次成功写入和 1 次失败写入 E11000 duplicate key error
和一个索引值,该索引值清楚地表明此失败是相关的使用给定列表中的第三个文档 (index == 2
)。
我通过 mongodb java api 3.6.1 和方法 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={ }}].
}
假设只有一个文档触发了重复键错误。所有其他 999 个文档已成功插入。
我如何知道哪个文档触发了错误?
当然,当出现重复键错误时,我可以用重复的 bar.id
搜索我的文档列表,但这很不方便(这意味着解析 WriteError 消息...),如果有两个List<Document>
中具有相同 bar.id
的文档,如果不询问数据库,几乎不可能知道是哪个触发了错误。
谢谢
MongoBulkWriteException
包含一个List<BulkWriteError>
,每次失败的写入将由这个列表中的一个元素表示。此列表中的每个元素都包含一个 index
属性,该属性由提供的文档列表中的元素索引填充。
因此,您可以使用此 index
来找出哪些提供的文档失败了。
这里有一个测试用例,展示了这一点:
@Test
public void canBulkWriteAndIdentifySpecificFailedDocuments() throws IOException {
MongoClient mongoClient = new MongoClientFactory().create();
MongoCollection<Document> collection = mongoClient.getDatabase("Whosebug").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"));
}
}
在这个测试用例中我们...
- 写文档
- 在目标集合上创建唯一索引
- 写入文档集合(使用
new InsertManyOptions().ordered(false)
进行无序写入),其中一个违反了唯一索引 - 断言批量插入导致抛出
MongoBulkWriteException
并且此异常报告 4 次成功写入和 1 次失败写入E11000 duplicate key error
和一个索引值,该索引值清楚地表明此失败是相关的使用给定列表中的第三个文档 (index == 2
)。