Roee Gavirel Roee Gavirel - 1 year ago 78
Java Question

Using ElasticSearch's script_upsert to create a document

According to the official documentation Update API - Upserts one can use

in order to handle update (for existing document) or insert (for new document) form within the script. The thing is they never show how the script should look to do that. The Java - Update API Doesn't have any information on the ScriptUpsert uses.

This is the code I'm using:

//My function to build and use the upsert
public void scriptedUpsert(String key, String parent, String scriptSource, Map<String, ? extends Object> parameters) {
Script script = new Script(scriptSource, ScriptType.INLINE, null, parameters);
UpdateRequest request = new UpdateRequest(index, type, key);
if (parent != null) {

//A test call to validate the function
String scriptSource = "if (!ctx._source.hasProperty(\"numbers\")) {ctx._source.numbers=[]}";
Map<String, List<Integer>> parameters = new HashMap<>();
List<Integer> numbers = new LinkedList<>();
parameters.put("numbers", numbers);

bulk.scriptedUpsert("testUser", null, scriptSource, parameters);

And I'm getting the following exception when "testUser" documents doesn't exists:

DocumentMissingException[[user][testUser]: document missing

How can I make the scriptUpsert work from the Java code?

Answer Source

This is how a scripted_upsert command should look like (and its script):

POST /sessions/session/1/_update
  "scripted_upsert": true,
  "script": {
    "script": "if (ctx.op == \"create\") ctx._source.numbers = newNumbers; else ctx._source.numbers += updatedNumbers",
    "params": {
      "newNumbers": [1,2,3],
      "updatedNumbers": [55]
  "upsert": {}

If you call the above command and the index doesn't exist, it will create it, together with the newNumbers values in the new documents. If you call again the exact same command the numbers values will become 1,2,3,55.

And in your case you are missing "upsert": {} part.