【Elasticsearch】Elasticsearch exception [type=version_conflict_engine_exception, reason=[type][_id]:

背景:

使用elasticsearch-rest-high-level-client 对ES进行更新操作,用seqNo来校验版本,现在报版本冲突错误如下:

Elasticsearch exception [type=version_conflict_engine_exception, reason=[type][_id]: version conflict, required seqNo [1222528], primary term [1]. current document has seqNo [1292133] and primary term [1]]

引用的maven文件

        <dependency>
			<groupId>org.elasticsearch.client</groupId>
			<artifactId>elasticsearch-rest-high-level-client</artifactId>
			<version>7.0.1</version>
		</dependency>

查看官网文档:https://www.elastic.co/guide/en/elasticsearch/reference/2.2/docs-update.html#_parameters_3,

 

发现有一个配置项 retry_on_conflict,代表更新失败时重连次数,那就加上,版本冲突报错减少

解决:

RestClientBuilder builder = RestClient.builder(new HttpHost("127.0.0.1", 9200, "http"));
//ssl认证
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("账号一般是elastic", "密码"));
builder.setHttpClientConfigCallback(f -> f.setDefaultCredentialsProvider(credentialsProvider));
builder.setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder
                            .setConnectTimeout(50000)
                            .setMaxRedirects(3)
                            .setSocketTimeout(150000));

RestHighLevelClient client = new RestHighLevelClient(builder);
JSONObject jObject = new JSONObject();
jObject.put("uu_id", 1);
jObject.put("username", "zhagnsan");
jObject.put("password", "password");
client.update(new UpdateRequest("index", "type", "更新ID").retryOnConflict(3)
                                        .docAsUpsert(true).doc(jObject), RequestOptions.DEFAULT);

有兴趣了解更多的可以看下面官网的解释,逐步加深理解

更新API

更新API允许基于提供的脚本来更新文档。该操作从索引中获取文档(与分片并置),运行脚本(具有可选的脚本语言和参数),并向后索引结果(还允许删除或忽略该操作)。它使用版本控制来确保在“获取”和“重新索引”期间未发生任何更新。

注意,此操作仍然意味着对文档进行完全重新索引,它只是消除了一些网络往返,并减少了获取和索引之间版本冲突的机会。_source需要启用此功能的字段。

例如,让我们为一个简单的文档建立索引:

curl - XPUT本地主机:9200 / test / type1 / 1 - d '{ “ counter” :1 ,“ tags” :[ “ red” ] } ' 

脚本更新

现在,我们可以执行一个脚本来增加计数器:

curl - XPOST'localhost :9200 / test / type1 / 1 / _update' - d '{ “ script” :{ “ inline” :“ ctx._source.counter + = count” ,“ params” :{ “ count” :4 } } } '

我们可以将标签添加到标签列表中(请注意,如果标签存在,它仍会添加标签,因为它是列表):

curl - XPOST'localhost :9200 / test / type1 / 1 / _update' - d '{ “ script” :{ “ inline” :“ ctx._source.tags + = tag” ,“ params” :{ “ tag” :“蓝色“ } } } ' 

此外_source,下列变量都可以通过ctx地图:_index_type_id_version_routing, _parent_timestamp_ttl

我们还可以在文档中添加一个新字段:

curl - XPOST'localhost :9200 / test / type1 / 1 / _update' - d '{ “ script” :“ ctx._source.name_of_new_field = \” value_of_new_field \“” } ' 

或从文档中删除一个字段:

curl - XPOST'localhost :9200 / test / type1 / 1 / _update' - d '{ “ script” :“ ctx._source.remove(\” name_of_field \“)” } ' 

而且,我们甚至可以更改执行的操作。如果tags字段包含blue,则此示例删除doc ,否则不执行任何操作(noop):

curl - XPOST'localhost :9200 / test / type1 / 1 / _update' - d '{ “ script” :{ “ inline” :“ ctx._source.tags.contains(tag)?ctx.op = \” delete \“ :ctx.op = \“ none \”“ ,” params“ :{ ” tag“ :” blue“ } } } ' 

使用部分文档进行更新

更新API还支持传递部分文档,该文档将合并到现有文档中(简单的递归合并,对象的内部合并,替换核心“键/值”和数组)。例如:

curl - XPOST'localhost :9200 / test / type1 / 1 / _update' - d '{ “ doc” :{ “ name” :“ new_name” } } ' 

如果同时指定docscript,则将doc被忽略。最好是将部分文档的字段对放在脚本本身中。

检测noop更新

如果doc指定,则其值将与现有合并_source。默认情况下,仅当新_source字段与旧字段不同时才对文档重新索引。设置detect_noopfalse会导致Elasticsearch始终更新文档,即使文档没有更改。例如:

curl - XPOST'localhost :9200 / test / type1 / 1 / _update' - d '{ “ doc” :{ “ name” :“ new_name” },“ detect_noop” :false } '

如果namenew_name在发送请求之前,则文档仍会重新编制索引。

增补

如果文档尚不存在,则upsert元素的内容将作为新文档插入。如果文档确实存在,则将 script改为执行:

curl - XPOST'localhost :9200 / test / type1 / 1 / _update' - d '{ “ script” :{ “ inline” :“ ctx._source.counter + = count” ,“ params” :{ “ count” :4 } },“ upsert” :{ “ counter” :1 } } ' 

scripted_upsert

如果您希望脚本运行而不管文档是否存在(即脚本处理初始化文档而不是 upsert元素),请设置scripted_upserttrue

curl - XPOST'localhost :9200 / sessions / session / dh3sgudg8gsrgl / _update' - d '{ “ scripted_upsert” :true ,“ script” :{ “ id” :“ my_web_session_summariser” ,“ params” :{ “ pageViewEvent” :{ “ url“ :” foo.com/bar“ ,” response“ :404 ,” time“ :” 2014-01-01 12:32“ } } },” upsert“ :{} } ' 

doc_as_upsert

设置为,而不是发送部分文档docupsert文档, 而是将的内容用作 值:doc_as_upserttruedocupsert

curl - XPOST'localhost :9200 / test / type1 / 1 / _update' - d '{ “ doc” :{ “ name” :“ new_name” },“ doc_as_upsert” :true } ' 

参量

更新操作支持以下查询字符串参数:

retry_on_conflict

在更新的获取和索引编制阶段之间,可能有另一个进程可能已经更新了同一文档。默认情况下,更新将因版本冲突异常而失败。该retry_on_conflict 参数控制在最终引发异常之前重试更新的次数。

routing

路由用于将更新请求路由到正确的分片,并且如果不存在要更新的文档,则为upsert请求设置路由。不能用于更新现有文档的路由。

parent

如果不存在要更新的文档,则使用父级将更新请求路由到正确的分片,并为更新请求设置父级。不能用于更新parent现有文档。

timeout

等待分片可用的超时。

consistency

索引/删除操作的写入一致性。

refresh

操作发生后立即刷新相关的主和副本分片(而不是整个索引),以便更新后的文档立即出现在搜索结果中。

fields

返回更新后的文档中的相关字段。指定_source返回完整的更新源。

version 和 version_type

更新API在内部使用Elasticsearch的版本控制支持,以确保文档在更新期间不会更改。您可以使用version 参数指定仅当文档版本与指定的版本匹配时才应对其进行更新。通过将版本类型设置为,force您可以在更新后强制使用新版本的文档(请谨慎使用!force 不能保证文档没有更改)。

 

更新API不支持外部版本控制

更新API不支持外部版本控制(版本类型externalexternal_gte),因为这会导致Elasticsearch版本号与外部系统不同步。请改用 indexAPI

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zsigner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值