ElasticSearch-update_by_query
2025-01-22 08:19:30    502 字   
This post is also available in English and alternative languages.

ElasticSearch版本:6.5.0(点击跳转官方文档)


1. ElasticSearch 查询更新

最近有个需求,需要 elasticsearch对文档进行局部更新,而且并不知道被更新文档的id。但是有能够定位到文档的其他字段信息,于是那些用id去定位文档的方法就不能用了。

翻API的时候看到了,update_by_query:查询更新。

update_by_query 会获取索引的快照。如果在获取快照时或者进行索引请求时文档发生改变,那么将会发生版本冲突。

update_by_query 不支持回滚,假如修改很多的文档,在修改过程中,有一个版本冲突,后续的更新动作会立即中止,但之前更新的不会被回滚。

这个查询更新API可以用来批量更新,需求需要。我先用条件精确查询出文档,然后再进行更新。

DSL样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /books/book/_update_by_query
{
"query": {
"bool": {
"must": [
{
"term": {
"_id": {
"value": "60"
}
}
}
]
}
},
"script": {
"source": "ctx._source['author']='张立波2222'"
}
}

Java-RestHighLevelClient

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* 查询更新(局部更新)
* <p>
* queryParam 例子:
* <p>
* <code>
* Map<String, Object> objectMap = new HashMap<>();<br>
* objectMap.put("news_id", "143851577156830217");<br>
* objectMap.put("category.keyword", "社会");<br>
* </code>
* <p>
* 当查询key为中文时,需要加'.keyword'精确查询,否则中文默认分词
*
* @param index 索引
* @param type 类型
* @param queryParam 查询条件
* @param updateKey 更新key
* @param updateValue 更新value值
*/
public BulkByScrollResponse updateDocumentByQuery(String index, String type, Map<String, Object> queryParam,
String updateKey, String updateValue) {

//query condition
BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
queryParam.forEach((k, v) -> queryBuilder.must(QueryBuilders.termQuery(k, v)));

//update condition
Script updateScript = new Script("ctx._source['" + updateKey + "']='" + updateValue + "'");

//assemble
UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest();
updateByQueryRequest.indices(index);
updateByQueryRequest.setDocTypes(type);
updateByQueryRequest.setQuery(queryBuilder);
updateByQueryRequest.setScript(updateScript);

return elasticsearchActionImpl.execute( (RestHighLevelClient restHighLevelClient) ->
restHighLevelClient.updateByQuery(updateByQueryRequest, RequestOptions.DEFAULT));
}

2. Reference