项目中需要定时对ElasticSearch的某些数据进行更新,数据量十几万,采用RestClient更新,在没有设置超时的情况下,报错如下:java.io.IOException: listener timeout after waiting for [30000] ms
一般通常的做法都是修改超时时间设置:
restClient = RestClient.builder(
new HttpHost(GSConstants.P_ES_HOST, GSConstants.P_ES_PORT, "http"))
.setMaxRetryTimeoutMillis(TIMEOUT)
.setHttpClientConfigCallback(new HttpClientConfigCallback(){
@Override
public HttpAsyncClientBuilder customizeHttpClient(
HttpAsyncClientBuilder httpClientBuilder) {
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom()
.setConnectTimeout(5*60*1000)//超时时间5分钟
.setSocketTimeout(5*60*1000)//这就是Socket超时时间设置
.setConnectionRequestTimeout(DEFAULT_CONNECTION_REQUEST_TIMEOUT_MILLIS);
httpClientBuilder.setDefaultRequestConfig(requestConfigBuilder.build());
return httpClientBuilder;
}
}).build();
update_by_query 顾名思义,通过查询更新,既先query出符合条件的内容再进行update操作,新增字段,修改字段值都可以满足,这个批量修改更符合我们的需求。
updateByQuery的调用首先获取索引的快照,对使用内部版本控制的任何文档进行索引。当版本匹配时,updateByQuery会更新文档并增加版本号。当一个文档在快照的时间和索引请求过程的时间之间发生变化时,就会发生版本冲突。为了防止版本冲突导致updateByQuery中止,设置终止冲突(false)。
所有更新和查询失败都会导致updateByQuery中止,任何成功的更新都是保留的,不会回滚。当第一个故障导致中止时,响应包含失败的批量请求所产生的所有故障。
UpdateByQueryRequestBuilder updateByQuery = UpdateByQueryAction.INSTANCE.newRequestBuilder(client);
updateByQuery.source("source_index")
.filter(QueryBuilders.termQuery("name", "alex"))
.size(1000)
.script(new Script(ScriptType.INLINE, "ctx._source.awesome = 'absolutely'", "painless", Collections.emptyMap()));
BulkByScrollResponse response = updateByQuery.get();
您可以使用这个访问来改变默认的滚动大小,或者对匹配文档的请求进行修改。