基于Vertx使用MongoDB BulkWriteWithOptions批量写入并获取状态
如何区分MongoDB批量插入中各文档的状态
我来帮你搞定这个批量插入后的状态区分问题!你已经用了bulkWriteWithOptions,核心关键点就是抓住MongoBulkWriteException——这个异常里藏着每一条操作的详细结果,刚好能帮你区分成功、失败和重复的文档。
先把你的代码补全并拆解关键逻辑:
mongoClient.bulkWriteWithOptions(collection, operations, options, repoAsyncResult -> { if (repoAsyncResult.failed()) { LOGGER.error("批量插入整体异常 : {}", repoAsyncResult.cause().getMessage()); // 重点:捕获批量写入专属异常 if (repoAsyncResult.cause() instanceof MongoBulkWriteException bulkEx) { // 获取已完成操作的统计结果 BulkWriteResult bulkResult = bulkEx.getResult(); // 统计成功插入的文档 LOGGER.info("成功插入 {} 条文档", bulkResult.getInsertedCount()); // 遍历所有失败的操作,区分重复和其他错误 List<BulkWriteError> errorDetails = bulkEx.getWriteErrors(); for (BulkWriteError error : errorDetails) { int docIndex = error.getIndex(); // 唯一键冲突(重复文档)的错误码是11000 if (error.getCode() == 11000) { LOGGER.warn("第 {} 条文档是重复项,已跳过:{}", docIndex, operations.get(docIndex)); } else { LOGGER.error("第 {} 条文档插入失败,错误码:{},原因:{},文档内容:{}", docIndex, error.getCode(), error.getMessage(), operations.get(docIndex)); } } } else { // 处理非批量写入类的异常(比如连接问题) LOGGER.error("非批量写入异常:", repoAsyncResult.cause()); } } else { // 所有操作都成功的情况 BulkWriteResult result = repoAsyncResult.get(); LOGGER.info("批量插入全部完成!成功插入 {} 条,无重复或失败文档", result.getInsertedCount()); } });
核心逻辑拆解:
MongoBulkWriteException是关键:这个异常专门对应批量写入的部分失败场景,它的getResult()能拿到已成功执行的操作统计,getWriteErrors()能拿到每一条失败操作的具体信息。- 三类文档的区分方式:
- 成功插入:直接通过
bulkResult.getInsertedCount()获取数量,若需要具体文档,可通过操作列表索引对应(成功场景一般无需额外处理)。 - 重复文档:唯一键冲突的错误码固定为
11000,在BulkWriteError里判断这个码就能精准识别重复项。 - 失败文档:除了11000之外的错误,都是其他原因导致的插入失败(比如字段类型不匹配、权限不足等),可以通过错误码和信息定位问题。
- 成功插入:直接通过
额外提醒:
如果你的批量操作包含upsert类型的指令(比如replaceOne带upsert:true),重复文档会被统计到getMatchedCount()或getUpsertedCount()里,这时候可以结合这些数值补充判断逻辑。
这样就能清晰地把批量插入里的成功、重复、失败文档都区分开啦!
内容的提问来源于stack exchange,提问作者Dipika
相关产品推荐
相关产品推荐

