I’m working on a Spring Boot application using Spring Data Elasticsearch, and I’m trying to execute a bulk update using a wildcard query and a script to update a field. Below is my service class:
considering this query can execute on Elasticsearch dev tools and update documents
@Slf4j
@Service
@RequiredArgsConstructor
public class ElasticsearchBulkUpdateService {
private final ElasticsearchOperations elasticsearchOperations;
public void updateProfitForPattern(String idPattern, String indexName) {
log.info("Executing simple query on index '{}':", indexName);
Query query = new StringQuery("""
{
"query": {
"wildcard": {
"id": {
"value": "*-14030701"
}
}
},
"script": {
"source": "
if (ctx._source.fundUnit != null) {
ctx._source.profit = ctx._source.fundUnit * 5;
}
",
"lang": "painless"
}
}
""");
UpdateQuery searchQuery = UpdateQuery.builder(query).build();
IndexCoordinates indexCoordinates = IndexCoordinates.of(indexName);
ByQueryResponse byQueryResponse = elasticsearchOperations.updateByQuery(searchQuery, indexCoordinates);
System.err.println(byQueryResponse);
}
}
When I run this code, I get the following exception:
org.springframework.data.elasticsearch.UncategorizedElasticsearchException: [es/update_by_query] failed: [parsing_exception] unknown query [query]
It seems like the Elasticsearch query is not being recognized correctly. I’m using Spring Data Elasticsearch with ElasticsearchOperations. Could anyone point out what I’m doing wrong or how I can fix this issue?
Spring boot version: 3.2.5
spring-boot-starter-data-elasticsearch Version: 5.2.5
This happens because an incorrectly structured request was sent to Elasticsearch for the UpdateQuery operation.
The UpdateQuery request needs to clearly differentiate between the query that identifies the documents to be updated and the script that outlines how to perform those updates. If these components are not properly separated, Elasticsearch will trigger a parsing exception.
I’ve made a few adjustments below,
@Slf4j
@Service
@RequiredArgsConstructor
public class ElasticsearchBulkUpdateService {
private final ElasticsearchOperations elasticsearchOperations;
public void updateProfitForPattern(String indexName) {
System.out.println("Executing simple query on index '{}':" + indexName);
// Define the wildcard query to find documents to update
String queryString = """
{
"query": {
"wildcard": {
"id": {
"value": "*-14030701"
}
}
}
}
""";
// Define the update script
String script = """
{
"script": {
"source": "
if (ctx._source.fundUnit != null) {
ctx._source.profit = ctx._source.fundUnit * 5;
}
",
"lang": "painless"
}
}
""";
UpdateQuery updateQuery = UpdateQuery.builder(queryString)
.withScript(script)
.build();
IndexCoordinates indexCoordinates = IndexCoordinates.of(indexName);
ByQueryResponse byQueryResponse = elasticsearchOperations.updateByQuery(updateQuery, indexCoordinates);
System.err.println(byQueryResponse);
}
}