Search code examples
javaelasticsearchelasticsearch-java-api

Update By Query in Elasticsearch using Java


I’m currently using Elasticsearch V2.3.1. I want to use the following Elasticsearch query in Java.

POST /twitter/_update_by_query
{
  "script": {
    "inline": "ctx._source.List = [‘Item 1’,’Item 2’]”
  },
  "query": {
    "term": {
      "user": "kimchy"
    }
  }
}

The above query searches for “user” named “kimchy” and updates the “List” field with given values. This query updates multiple documents at the same time. I read about the Update API for Java here https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.3/java-docs-update.html but couldn’t find what I was looking for. The Update API for Java only talks about updating single document at a time. Is there any way to update multiple documents? Sorry if I’m missing something obvious. Thank you for your time.

Update:

I tried the below Java Code:

Client client = TransportClient.builder().addPlugin(ReindexPlugin.class)
    .build().addTransportAddress(new InetSocketTransportAddress(
        InetAddress.getByName("127.0.0.1"), 9300));

UpdateByQueryRequestBuilder ubqrb = UpdateByQueryAction.INSTANCE
    .newRequestBuilder(client);

Script script = new Script("ctx._source.List = [\"Item 1\",\"Item 2\"]");

//termQuery is not recognised by the program
BulkIndexByScrollResponse r = ubqrb.source("twitter").script(script)
    .filter(termQuery("user", "kimchy")).execute().get();

So I edited the Java Program as above and the termQuery is not identified by Java. May I know what I'm doing wrong here? Thanks.


Solution

  • As of ES 2.3, the update by query feature is available as the REST endpoint _update_by_query but nor for Java clients. In order to call this endpoint from your Java client code, you need to include the reindex module in your pom.xml, like this

    <dependency>
        <groupId>org.elasticsearch.module</groupId>
        <artifactId>reindex</artifactId>
        <version>2.3.2</version>
    </dependency>
    

    Then you need to include this module when building your client:

    clientBuilder.addPlugin(ReindexPlugin.class);
    

    Finally you can call it like this:

    UpdateByQueryRequestBuilder ubqrb = UpdateByQueryAction.INSTANCE.newRequestBuilder(client);
    
    Script script = new Script("ctx._source.List = [\"Item 1\",\"Item 2\"]");
    
    BulkIndexByScrollResponse r = ubqrb.source("twitter")
        .script(script)
        .filter(termQuery("user", "kimchy"))
        .get();
    

    UPDATE

    If you need to specify the type(s) the update should focus on, you can do so:

    ubqrb.source("twitter").source().setTypes("type1");
    BulkIndexByScrollResponse r = ubqrb.script(script)
        .filter(termQuery("user", "kimchy"))
        .get();