Handling Exception when bulkwrite with ordered as False in MongoDB java

时间:2016-02-03 04:12:12

标签: mongodb mongodb-query mongodb-java

I am Using the Mongo DB java driver:

collection.bulkWrite(documents);

I have 1000000 records to be inserted.If insertion of one of the records failed then on the first failure the remaining records wont get inserted.. In order to avoid this found that there are bulkwrite options with ordered as false;

collection.bulkWrite(documents, new BulkWriteOptions().ordered(false) )

If any exception occurs during the above operation.Can we get the list of the records for which bulkwrite failed and can we try inserting those records again:?

2 个答案:

答案 0 :(得分:3)

我认为你正在寻找类似的东西......

{{1}}

答案 1 :(得分:0)

所有失败的bulkWrite操作都会在返回文档的数组中报告,并且无法插入完整的文档。例如,这段代码通过java驱动程序:

MongoCollection<Document> collection = database.getCollection("bulk");

List<WriteModel<Document>> writes = new ArrayList<WriteModel<Document>>();
 writes.add(new InsertOneModel<Document>(new Document("_id", 1)));
 writes.add(new InsertOneModel<Document>(new Document("_id", 2)));
 writes.add(new InsertOneModel<Document>(new Document("_id", 2)));
 writes.add(new InsertOneModel<Document>(new Document("_id", 4)));
BulkWriteResult bulkWriteResult = collection.bulkWrite(writes);

System.out.println(bulkWriteResult.toString());

返回:

Exception in thread "main" com.mongodb.MongoBulkWriteException: 
  Bulk write operation error on server localhost:27017. Write errors:
  [BulkWriteError{index=2, code=11000, message='E11000 duplicate key 
  error collection: test.bulk index: _id_ dup key: { : 2 }',
  details={ }}].

你没有提到你正在使用的MongoDB版本,但是这里是无序的bulkWrites的版本3.2手册条目:https://docs.mongodb.org/manual/core/bulk-write-operations/如果你想进一步研究它。

但是,如果你在加载操作过程中出现“异常”意味着客户端或mongod进程崩溃,或者发生硬件或网络事件,那么批量写入就不会有干净的退出,因此没有bulkWriteResult输出如上。无序的bulkWrites并行执行操作,不一定按输入的顺序执行操作,对于分片集合和分布式集群,它更加复杂,因此无法确切知道在崩溃之前完成了哪些操作。唯一的解决方案是重复整个作业,这通常要求您删除第一次成功插入的所有文档。

如果您要加载到新的或空的集合,您可以简单地删除并重新创建它。如果存在带索引的唯一键,则可以重复加载,因为第一次插入OK的文档将作为重复项被拒绝。否则,您必须运行清理作业以删除在开始重新加载尝试之前可能/应该已插入的所有文档,如果它们不容易识别,则可能会出现问题。

这种情况的最佳方法是将大型加载操作分解为更小的部分,因此您有四个加载作业,每个加载作业有四分之一的数据(或者每个加载20%的数据,依此类推)。以这种方式设计加载过程需要付出更多的努力,但是使用5%的总数据重复一个作业要比重复单个95%标记失败的加载要快得多。

如果为每个作业添加一个具有不同值的loadNum字段,则count(“loadNum”:n)可用于确认所有已加载的文档,并删除(“loadNum”:n)将删除来自一份仅部分成功的工作的所有文件。