11

我目前正在使用 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”的“用户”并使用给定值更新“列表”字段。此查询同时更新多个文档。我在这里阅读了有关 Java 的更新 API https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.3/java-docs-update.html但找不到我要找的东西. 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识别。我可以知道我在这里做错了什么吗?谢谢。

4

2 回答 2

16

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

<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();
于 2016-05-05T03:49:30.963 回答
3

在 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);
于 2020-09-14T12:33:54.137 回答