Reputation: 2134
I have a elasticsearch index (lets name it student) . I have the fields
{ "name","division" ,"class" , "studentRollNo"} .
Is it possible to to update elasticsearch index for on record whose name would be "ABC" . With update API I can only update it by id ,with Update with query how can I pass the jsonString . Lets say My json String for update would be
Existing :
{ "name":"abc" , "division":"D","class" :10 ,"studentRollNo":23}
To Update :
{"name":"abc" , "division" : A , "class" : 11 , "studentRollNo" : 23}
Upvotes: 1
Views: 2545
Reputation: 233
Since there is no good official support or examples for ES 8.x version Adding snippet for that as well which i tried and worked (this is for 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());
Upvotes: 0
Reputation: 5486
I am not sure which elasticsearch version you are using but below is code snippet for ES 7.13 version.
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();
Below is equivalent update by query 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
}
}
}
}
Upvotes: 3