Elasticsearch构建空BulkRequest报缺少operations属性异常如何解决
Elasticsearch BulkRequest构建前空操作判断方案
异常原因
新版Elasticsearch Java客户端在构建请求实例时会强制校验必填属性,BulkRequest的operations字段为必填项,当BulkRequest.Builder未添加任何批量操作时,直接调用build()方法就会抛出MissingRequiredPropertyException: Missing required property 'BulkRequest.operations'异常,你之前写的「先build再判断operations是否为空」的逻辑完全走不通,因为校验发生在build阶段,执行顺序早于空判断。
可行解决方法
- 自定义计数标记(推荐,无兼容风险)
不需要依赖Builder的内部状态,在业务逻辑层单独维护一个操作计数变量,每向Builder添加一个批量操作就给计数加1,最终判断计数大于0时再执行build和请求提交逻辑,示例代码如下:
这个方案完全不依赖客户端内部实现,不管ES客户端版本怎么升级都不会失效,逻辑可控排查问题也简单。// 初始化批量操作计数 int bulkOperationCount = 0; // 原有业务添加操作的逻辑 if (Some Condition) { // 将处理后的对象加入批量请求 bulkRequestBuilder.operations(op -> op.index(idx -> idx .id(esKey) .document(JSON OBJECT))); bulkOperationCount++; } else { log.info("I am not building any bulk request.", esKey); } // 提交前判断 if (bulkOperationCount > 0) { BulkRequest bulkRequest = bulkRequestBuilder.build(); BulkResponse bulkResponse = repo.saveToIndexByBulkRequest(bulkRequest); } - 反射读取Builder内部存储(不推荐,存在兼容风险)
从BulkRequest.Builder的源码实现看,内部维护了一个List类型的集合存储已添加的operations,可以通过反射读取该集合的长度判断是否有操作,但ES客户端迭代时可能随意修改内部成员变量的命名、存储结构,会导致反射逻辑突然失效,生产环境不建议使用。
注意:不要尝试通过给Builder注入空列表的方式绕过build校验,Elasticsearch服务端收到无任何有效操作的Bulk请求时同样会返回参数错误,这类请求本身就没有发送的必要。
内容的提问来源于stack exchange,提问作者kaushik mn
相关产品推荐
相关产品推荐

