MongoDB Java:如何获取写入错误文档?

MongoDB Java:如何获取写入错误文档?,java,mongodb,bulkinsert,mongodb-java,Java,Mongodb,Bulkinsert,Mongodb Java,我通过mongodb java api 3.6.1和方法insertMany(List)在mongodb 3.6中一次插入1000个文档 假设只有一个文档触发了重复密钥错误。已成功插入所有其他999个文档。 我如何知道是哪个文档触发了错误? 当然,当获得重复键错误时,我可以使用重复的bar.id搜索我的文档列表,但这很不方便(这意味着解析WriteError消息…),如果列表中有两个具有相同bar.id,则,如果不询问数据库,几乎不可能知道是哪个触发了错误 感谢MongoBulkWriteExc

我通过mongodb java api 3.6.1和方法
insertMany(List)
在mongodb 3.6中一次插入1000个文档

假设只有一个文档触发了重复密钥错误。已成功插入所有其他999个文档。
我如何知道是哪个文档触发了错误?

当然,当获得重复键错误时,我可以使用重复的
bar.id
搜索我的文档列表,但这很不方便(这意味着解析WriteError消息…),如果
列表中有两个具有相同
bar.id
,则,如果不询问数据库,几乎不可能知道是哪个触发了错误


感谢

MongoBulkWriteException
包含一个
列表
,每个失败的写入都将由该列表中的一个元素表示。此列表中的每个元素都包含一个
索引
属性,该属性由提供的文档列表中元素的索引填充

因此,您可以使用此
索引
来确定提供的文档中哪些失败

下面是一个测试用例,展示了这一点:

@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"));
    }
}
@测试
public void可以BulkWriteAndifySpecificFailedDocuments()引发IOException{
MongoClient MongoClient=new MongoClientFactory().create();
MongoCollection collection=mongoClient.getDatabase(“stackoverflow”).getCollection(“bulkwrite”);
//重新开始这个测试用例
collection.drop();
Document knownDocument=new Document();
收藏。insertOne(已知文档);
createIndex(新的BasicDBObject(“name”,1),新的IndexOptions().unique(true));
int createDuplicationIndex=2;
List docs=Lists.newArrayList();
对于(int i=0;i<5;i++){
如果(i==createDuplicationIndex){
//故意触发重复密钥异常
添加文件(已知文件);
}否则{
docs.add(new Document().append(“name”,new BsonString(“beep”+i)));
}
}
试一试{
collection.insertMany(docs,new insertmanyooptions().ordered(false));
}捕获(MongoBulkWriteEx){
断言(例如getWriteResult().getInsertedCount(),为(4));
断言(例如getMessage(),包含字符串(“重复键错误”);
资产(例如getWriteErrors().size())为(1));
断言(例如getWriteErrors().get(0.getIndex())是(createDuplicationIndex));
断言(例如getWriteErrors().get(0.getCode())为(11000));
断言(例如getWriteErrors().get(0).getMessage(),StartWith(“E11000重复密钥错误”);
}
}
在这个测试用例中,我们

  • 写一份文件
  • 在目标集合上创建唯一索引
  • 编写文档集合(对于无序写入,使用
    new insertmanyooptions().ordered(false)
    ),其中一个文档违反了唯一索引
  • 断言大容量插入导致抛出一个
    MongoBulkWriteException
    ,该异常报告4次成功写入,1次写入失败,出现
    E11000重复键错误
    ,并且一个索引值清楚地表明该故障与第三个文档相关(
    index==2
    )在给定的列表中

  • 这有关系吗?可能是,但我的问题更一般,因为任何其他写入错误都可能发生。
    @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"));
        }
    }