Conditional Updates in Elasticsearch Using the Java High-Level REST Client
This article explains how to perform both single‑document and conditional bulk updates in Elasticsearch with the Java high‑level REST client, demonstrating UpdateRequest, UpdateByQueryRequest, scripting for field modifications, handling arrays, and providing a reusable utility method for generic updates.
ElasticSearch is increasingly popular for log, product, and order search, with most use cases involving periodic data imports or CDC to build indexes, typically updating documents one by one.
Sometimes batch updates are needed, similar to MySQL's UPDATE table SET column=value WHERE condition , and this guide shows how to achieve that in Elasticsearch.
Single Document Update
The official client recommendation is elasticsearch‑rest‑high‑level‑client . A single document update is performed by constructing an UpdateRequest with index, type, and id, then calling restHighLevelClient.update :
UpdateRequest updateRequest = new UpdateRequest(index, type, id);
updateRequest.doc(documentJson, XContentType.JSON);
restHighLevelClient.update(updateRequest, options);This targets a specific document by its ID.
Conditional Update
To set status=0 for all documents where userId=1 , use the _update_by_query API with a script and a term query:
POST http://47.105.66.210:9200/article_v1/doc/_update_by_query
{
"script": {"source":"ctx._source['status']=0;"},
"query": {"term": {"userId": 1}}
}In Java, the same operation is built with UpdateByQueryRequest :
UpdateByQueryRequest request = new UpdateByQueryRequest("article_v1");
request.setQuery(new TermQueryBuilder("userId", 1));
request.setScript(new Script("ctx._source['status']=0;"));
restHighLevelClient.updateByQuery(request, RequestOptions.DEFAULT);Conditional Update of Arrays
To remove the tag java from the tags array for the same users, modify the script:
POST http://47.105.66.210:9200/article_v1/doc/_update_by_query
{
"script": {"source":"ctx._source['tags'].removeIf(item -> item == 'java');"},
"query": {"term": {"userId": 1}}
}Adding an element is as simple as replacing removeIf with add :
ctx._source['tags'].add('java');More complex logic can be embedded in the script, e.g., only add when type == 11 :
POST http://47.105.66.210:9200/article_v1/doc/_update_by_query
{
"script": {"source":"if(ctx._source.type == 11) {ctx._source['tags'].add('java');}"},
"query": {"term": {"userId": 1}}
}Encapsulating a Generic Conditional Update
For repetitive update patterns, a utility method can build a dynamic script from a map of fields and values, handling numbers, strings, and lists, then execute the update via UpdateByQueryRequest :
public BulkByScrollResponse updateByQuery(String index, QueryBuilder query, Map<String, Object> document) {
UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(index);
updateByQueryRequest.setQuery(query);
StringBuilder script = new StringBuilder();
for (String key : document.keySet()) {
Object value = document.get(key);
String appendValue;
if (value instanceof Number) {appendValue = value.toString();}
else if (value instanceof String) {appendValue = "'" + value + "'";}
else if (value instanceof List) {appendValue = JsonUtils.toJson(value);}
else {appendValue = value.toString();}
script.append("ctx._source.").append(key).append("=").append(appendValue).append(";");
}
updateByQueryRequest.setScript(new Script(script.toString()));
return updateByQuery(updateByQueryRequest, RequestOptions.DEFAULT);
}
public BulkByScrollResponse updateByQuery(UpdateByQueryRequest updateByQueryRequest, RequestOptions options) {
return CatTransactionManager.newTransaction(() -> {
try {
return restHighLevelClient.updateByQuery(updateByQueryRequest, options);
} catch (IOException e) { throw new RuntimeException(e); }
}, ElasticSearchConstant.ES_CAT_TYPE, ElasticSearchConstant.UPDATE, Collections.emptyMap());
}Usage example:
@Test
public void testUpdate5() {
Map<String, Object> document = new HashMap<>();
document.put("title", "Java");
document.put("status", 0);
document.put("tags", Lists.newArrayList("JS", "CSS"));
kittyRestHighLevelClient.updateByQuery(elasticSearchIndexConfig.getArticleSaveIndexName(), new TermQueryBuilder("userId", 1), document);
}Author
Yin Jihuan, a technology enthusiast and author of "Spring Cloud Microservices – Full‑Stack Techniques and Case Studies" and "Spring Cloud Microservices: Beginner to Advanced", also the founder of the public account "Yuan Tiandi".
References
• Elasticsearch Update By Query API
• Elasticsearch Scripting Documentation
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.