3

I'm trying to update a nested object in Elasticsearch via the Java API, using a technique similar to what is outlined here. The problem is how to pass the json into the script. If I just blindly concatenate the json to the script string as suggested here, the Groovy does not compile. If you pass it in directly as a parameter, it just gets parsed as a string. If I try to use JsonSlurper, like:

String script = "ctx._source.pete = new groovy.json.JsonSlurper().parseText(json)";
Map<String, Object> params = ImmutableMap.of("json", json);
return new Script(script, ScriptService.ScriptType.INLINE, null, params);

I get a compilation exception: unable to resolve class groovy.json.JsonSlurper

A further problem with the JsonSlurper approach seems to be that the Elasticsearch team has basically disabled it in 2.2.

Does anyone know how to pass the json in correctly via the Java API?

3
  • can you try to add import groovy.json.JsonSlurper; at the beginning of your script? Just to see if that compilation error gets out? Commented Mar 1, 2016 at 16:38
  • @Val Unfortunately that doesn't help, same error. Commented Mar 1, 2016 at 16:40
  • Was worth a try, though it's pretty clear why this has been disabled and why the ES folks stand firm by that decision. Commented Mar 1, 2016 at 16:43

2 Answers 2

4

Thanks to the guys at Elasticsearch for helping me with this. The answer is to convert the JSON to a Map and then just pass the Map as a param:

String script = "ctx._source.pete = jsonMap";
Map<? ,?> jsonMap = new ObjectMapper().readValue(json, HashMap.class);
Map<String, Object> params = ImmutableMap.of("jsonMap", jsonMap);
return new Script(script, ScriptService.ScriptType.INLINE, null, params);

I'm using org.codehaus.jackson.map.ObjectMapper to do the conversion from JSON to the Map.

Sign up to request clarification or add additional context in comments.

Comments

-1

I have written an extensive answer on that subject on StackOverflow in this thread. Instead of a script, I used the UpdateRequest class in Java, which you have to feed with a XContentBuilder object containing all the changes you wish to perform.

This is a snippet of the answer:

UpdateRequest updateRequest = new UpdateRequest();
//....
XContentBuilder jb = XContentFactory.jsonBuilder();
jb.startObject();
jb.startArray("..");

for ( /**/) {
   jb.startObject()
   .field("attrX", value)
   // ..
   .startObject("attrY")
   .field("attrZ", value)
   .endObject()
   .field("atrrW", value)
   .endObject();
}
jb.endArray();
b.endObject();
updateRequest.doc(jb);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.