使用外部版本控制时ElasticSearch更新文档及upsert操作报错如何解决
报错根因
Elasticsearch 从7.x版本开始,Update API 已经完全废弃了基于version参数的乐观并发控制能力,无论你指定version_type为external还是其他类型,只要请求里携带了version参数,就会触发这个校验报错。
官方之所以做这个调整,是因为7.x之后统一推出了基于if_seq_no和if_primary_term的乐观锁方案,替代旧的版本号控制逻辑,目前只有全量写入的Index API还保留了对version+version_type=external参数的兼容支持,Update API没有做对应兼容。
解决方案
你要实现基于时间戳的外部版本控制upsert需求,可选用以下两种方式:
- 方案一:改用Index API实现upsert,可直接沿用现有的外部版本号逻辑,请求示例如下:
PUT indexName/_doc/id?version=1234568&version_type=external&op_type=index { // 你的完整文档内容 }
如果你的upsert逻辑不需要做局部字段更新,只是要完整覆盖或者写入新文档,这个方案成本最低,完全适配你现有的版本控制逻辑。
- 方案二:如果必须使用Update API做局部字段更新,需要调整你的版本控制逻辑:
- 先查询目标文档的
_seq_no、_primary_term,以及你存储在文档自定义字段里的外部版本号(比如ext_version) - 比对你要传入的时间版本号是否大于文档现有
ext_version,如果满足条件,调用Update API时携带if_seq_no和if_primary_term参数做并发控制,同时更新文档的ext_version字段为新的时间戳。
- 先查询目标文档的
内容的提问来源于stack exchange,提问作者Sidharth Ramesh
相关产品推荐
相关产品推荐

