【问题标题】:Update By Query in Elasticsearch using Java使用 Java 在 Elasticsearch 中按查询更新
【发布时间】:2016-08-30 13:12:12
【问题描述】:

我目前使用的是 Elasticsearch V2.3.1。我想在 Java 中使用以下 Elasticsearch 查询。

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

上述查询搜索名为“kimchy”的“用户”,并使用给定值更新“列表”字段。此查询同时更新多个文档。 我在这里 https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.3/java-docs-update.html 阅读了有关 Java 更新 API 的信息,但找不到我要找的东西。 Java 的更新 API 只讨论一次更新单个文档。有没有办法更新多个文档?抱歉,如果我遗漏了一些明显的东西。感谢您的时间。

更新:

我尝试了以下 Java 代码:

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();

所以我像上面那样编辑了 Java 程序,但 termQuery 没有被 Java 识别。我可以知道我在这里做错了什么吗?谢谢。

【问题讨论】:

    标签: java elasticsearch elasticsearch-java-api


    【解决方案1】:

    从 ES 2.3 开始,按查询更新功能可作为 REST 端点 _update_by_query 使用,但不适用于 Java 客户端。为了从您的 Java 客户端代码调用此端点,您需要在 pom.xml 中包含 reindex 模块,如下所示

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

    那么你需要在构建你的客户端时包含这个模块:

    clientBuilder.addPlugin(ReindexPlugin.class);
    

    终于可以这样称呼了:

    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();
    

    更新

    如果您需要指定更新应该关注的类型,您可以这样做:

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

    【讨论】:

    • 您需要添加import static org.elasticsearch.index.query.QueryBuilders.termQuery;
    • 嗨@Val,它工作但这种方式(使用 BulkIndexByScrollResponse 中的过滤器)我只能更新一个用户名为“Kimchy”的文档。是否可以在 BulkIndexByScrollResponse 中使用 setQuery 更新多个文档?或者可能有任何其他方式?
    • 当然,您可以制作任何类型的查询。那只是一个例子。你有什么疑问?
    • 嗨@Val,这是他们在此类查询中设置文档类型的一种方式。
    • 对于那些使用 ES 版本 5.5.0 或类似版本的人的提示:该插件必须作为第二个参数添加到 PreBuiltTransportClient 的构造函数中。
    【解决方案2】:

    在 ES 7.9 中,这也适用于 UpdateByQueryRequest

    Map<String, Object> map = new HashMap<String, Object>();
    
    UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest("indexName");
    updateByQueryRequest.setConflicts("proceed");
    updateByQueryRequest.setQuery(new TermQueryBuilder("_id", documentId));
    Script script = new Script(ScriptType.INLINE, "painless",
            "ctx._source = params", map);
    updateByQueryRequest.setScript(script);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-25
      • 2017-07-18
      • 1970-01-01
      • 2017-09-06
      相关资源
      最近更新 更多