使用Elasticsearch update_by_query时,如何判断所有文档已正确更新?
确认Elasticsearch update_by_query完成所有匹配文档更新的方法
在使用Elasticsearch的_update_by_query接口批量更新文档时,如何确保所有匹配查询条件的文档都被正确更新?
请求示例
- 请求URL:
http://localhost:9200/user/_update_by_query?conflicts=proceed - 请求体:
{ "script": { "source": "ctx._source.age = params.age", "lang": "painless", "params": { "age": 10 } }, "size": 1000, "query": { "term": { "age": { "value": 20, "boost": 1.0 } } } }
响应示例
{ "took": 28, "timed_out": false, "total": 1, "updated": 1, "deleted": 0, "batches": 1, "version_conflicts": 0, "noops": 0, "retries": { "bulk": 0, "search": 0 }, "throttled_millis": 0, "requests_per_second": -1.0, "throttled_until_millis": 0, "failures": [] }
关键字段含义澄清
先明确几个核心字段的实际意义,避免判断逻辑出错:
- total:查询语句匹配到的文档总数,即本次
update_by_query需要处理的文档总量 - updated:实际被成功修改的文档数(若文档目标字段值已和要设置的值一致,这类文档不会计入
updated,而是统计在noops字段) - noops:查询匹配但无需更新(字段值无变化)的文档数
- version_conflicts:更新过程中出现版本冲突的文档数
- failures:更新失败的文档详情列表
两种校验方案分析
方案一:通过total与updated的相等性判断
if (response.getTotal() == response.getUpdated()) { //所有文档已更新 } else { //部分文档更新失败,稍后重试 }
局限性:仅在所有匹配文档都需要被修改(即noops为0)的场景下有效。若存在部分文档字段值已符合预期(noops>0),total会大于updated,但这类文档不属于更新失败,该方案会误判。
方案二:通过版本冲突和失败列表判断
if (response.getVersionConflicts() == 0 && CollectionUtils.isEmpty(response.getFailures())) { //所有文档已更新 } else { //部分文档更新失败,稍后重试 }
准确性更高:
version_conflicts == 0表示没有文档因版本冲突导致更新失败failures为空表示没有其他原因(如脚本错误、文档不存在等)导致的更新失败
如果需要更严谨的校验,可以结合noops字段,确认所有匹配文档要么被成功更新,要么本身无需更新:
if (response.getVersionConflicts() == 0 && CollectionUtils.isEmpty(response.getFailures()) && (response.getTotal() == response.getUpdated() + response.getNoops())) { //所有匹配文档要么被成功更新,要么无需更新,无失败 }
内容的提问来源于stack exchange,提问作者winston
相关产品推荐
相关产品推荐

