Elasticsearch执行updateByQuery更新不存在文档无报错如何判断是否生效
根因分析
你当前的UpdateByQueryRequest没有显式设置查询条件,默认会匹配索引内的全部文档(你当前索引共2个文档),所有被匹配到的文档都会执行脚本逻辑。默认情况下,只要文档被脚本处理过,哪怕没有触发实际的字段修改,ES也会将其计入updated计数,所以两种场景下返回的updated值都是2,没有差异。
解决方案
方案1(推荐,性能最优):将过滤逻辑移到查询条件中
直接通过ES查询过滤出需要更新的文档,仅匹配条件的文档才会被后续处理,此时返回的updated计数就是实际被修改的文档数,同时可以避免全索引扫描,性能提升明显。
修改后的代码示例:
import org.elasticsearch.index.query.QueryBuilders; // ...其他代码不变 UpdateByQueryRequest request = new UpdateByQueryRequest("index"); Map<String, Object> data = new HashMap<>(); data.put("marks", "30"); data.put("name", "timmy"); data.put("roll_number", "10"); // 新增查询过滤条件,仅匹配name和roll_number符合要求的文档 request.setQuery(QueryBuilders.boolQuery() .must(QueryBuilders.termQuery("name", data.get("name"))) .must(QueryBuilders.termQuery("roll_number", data.get("roll_number"))) ); // 脚本无需再做条件判断,直接更新字段即可 request.setScript( new Script( ScriptType.INLINE, "painless", "ctx._source.marks=params.marks;", data)); BulkByScrollResponse resp = globalClient.updateByQuery(request, RequestOptions.DEFAULT); log.info("response: {}",resp.getStatus()); // 判断是否有文档被更新 if (resp.getUpdated() == 0) { log.info("本次更新无匹配文档,未执行修改操作"); }
方案2:脚本中显式标记无修改的文档为noop
如果你需要保留脚本内的判断逻辑,可以在条件不匹配时主动将操作标记为noop(无操作),此时未修改的文档会被计入noops计数,不会占用updated的计数:
修改后的脚本内容:
if (ctx._source.name == params.name && ctx._source.roll_number == params.roll_number) { ctx._source.marks=params.marks; } else { // 标记为无操作,不计入updated计数 ctx.op = 'noop'; }
修改后同样通过resp.getUpdated() > 0即可判断是否有文档被实际更新。
内容的提问来源于stack exchange,提问作者user2281204
相关产品推荐
相关产品推荐

