使用Java API根据条件更新ElasticSearch文档

agyaoht7  于 2023-02-14  发布在  Java
关注(0)|答案(2)|浏览(325)

我有一个ElasticSearch索引(我们将其命名为student)。
{"姓名"、"部门"、"班级"、"学生登记号"}。
是否可以更新名称为"ABC"的记录的ElasticSearch索引。使用更新API,我只能通过ID更新它,使用查询更新,我如何传递jsonString。假设我的json更新字符串为
现有:
{"姓名":" abc ","部门":" D ","班级":10,"学生登记号":23}
待更新:
{"名称":" abc ","部门":一、"类":11、"学生号":二十三岁

bihw5rsg

bihw5rsg1#

我不确定您使用的是哪个elasticsearch版本,但下面是ES 7.13版本的代码片段。

RestHighLevelClient client = new RestHighLevelClient(
            RestClient.builder(new HttpHost("localhost", 9200, "http")));

    UpdateByQueryRequest request = new UpdateByQueryRequest("student");
    request.setQuery(new TermQueryBuilder("name", "abc"));

    // This data map you can directly create from JSON string as well.
    Map<String, Object> data = new HashMap<String, Object>();
    data.put("name", "abc");
    data.put("division", "A");
    data.put("class", 11);
    data.put("studentRollNo", 23);

    Map<String, Object> param = new HashMap<String, Object>();
    param.put("data", data);

    // script will read data param value and assign to document source
    String source = "ctx._source=params.data";
    Script script = new Script(ScriptType.INLINE, "painless", source, param);

    request.setScript(script);
    client.updateByQuery(request, RequestOptions.DEFAULT);
    client.close();

以下是通过查询rest API json进行的等效更新:

POST student/_update_by_query
{
  "query": {
    "term": {
      "name": {
        "value": "abc"
      }
    }
  },
  "script": {
    "source": "ctx._source=params.data",
    "params": {
      "data": {
        "name": "abc",
        "division": "A",
        "class": 11,
        "studentRollNo": 23
      }
    }
  }
}
laik7k3q

laik7k3q2#

由于没有很好的官方支持或ES 8.x版本的例子添加片段,以及我尝试和工作(这是为8. 4. 3)

SSLContext sslContext = getSSLContext();

BasicCredentialsProvider credsProv = new BasicCredentialsProvider();

credsProv.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username,password));
    
RestClient restClient = RestClient.builder(new HttpHost(host, port, port == 443 ? "https" : "http"))
                                                .setHttpClientConfigCallback(hc -> hc.setSSLContext(sslContext).setDefaultCredentialsProvider(credsProv))
                                                  .build();
    
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());

ElasticsearchClient elasticsearchClient = new ElasticsearchClient(transport);


UpdateByQueryRequest.Builder builder = new UpdateByQueryRequest.Builder();

        builder.query(getBoolQuery()._toQuery()); // it will be of type BoolQuery.of(query -> { ... })._toQuery()

        InlineScript inlineScript = new InlineScript.Builder()
                .lang("painless")
                .source(getScriptSourceV8()) // it will be string type like "ctx._source=params";
                .params(getScriptParamsV8()) // it will be map of <String, JsonData>
                .build();

        Script script = new Script.Builder()
                .inline(inlineScript)
                .build();
        builder.script(script);

        builder.index("esIndex");
        builder.preference("_shards:"+shard);
        builder.timeout(new Time.Builder().time(TIMEOUT_UPDATE_BY_QUERY+"s").build());
        builder.conflicts(Conflicts.Proceed);

        UpdateByQueryResponse response = elasticsearchClient.updateByQuery(builder.build());

相关问题