Error when updating an array element object using java rest client api

I am trying to update an array element in the document. The update should replace an existing element.

This is what the document looks like

    "first" : "johnny",
    "last" : "gaudreau",
    "elements" : [
    {
       "OUI" : "AAAAAA",
       "SerialNumber" : "00000001AA"
    },
    {
       "OUI" : "00D09E",
       "SerialNumber" : "00000001B"
    },
    {
       "OUI" : "00D09E",
       "SerialNumber" : "00000001C"
    }
  ]

I can update the element object with the following curl command using the script option

    curl -X POST "localhost:9200/PlayerIndex/_update/1?pretty" -H 'Content-Type: application/json' -d'
    {
      "script": {
        "lang": "painless",
        "source": "for (int i=0; i < ctx._source.elements.length; i++) {if (ctx._source.elements[i].SerialNumber == params.sn) { ctx._source.elements[i] = params.newElement }}",
        "params": {
          "sn": "00000001AA",
          "newElement": {"OUI":"00D09E", "SerialNumber":"00000001AB"}
        }
      }
    }
    '

However, when I try to do the same in Java with the following code I get the following exception

[ElasticsearchException[Elasticsearch exception [type=mapper_parsing_exception, reason=object mapping for [element] tried to parse field [null] as object, but found a concrete value]]]

Here is the Java code

    final String updateElementScript = "for (int i=0; i < ctx._source.elements.length; i++) {if (ctx._source.elements[i].SerialNumber == params.sn) { ctx._source.elements[i] = params.newElement; }}";

    Map<String, Object> params = new HashMap<>();
    params.put("sn", "00000001AA");
    params.put("newElement", "{\"OUI\":\"00D09E\", \"SerialNumber\":\"00000001AB\"}");

    UpdateRequest request = new UpdateRequest().index("PlayerIndex").id("1");
                request.script(new Script(ScriptType.INLINE,
                        "painless",
                        updateElementScript,   
                        params));

    client.update(request, RequestOptions.DEFAULT);    // RestHighLevelClient

I have verified that I can update the field in the element object (e.g. the OUI field). But I want to update the whole element object. It seems like the Java code does not see the "newElement" as an object but a value. What am I doing wrong?

Found a solution based on this post

The solution is to convert your json object to a map using the Jackson ObjectMapper before adding it to the params map.

    final String updateElementScript = "for (int i=0; i < ctx._source.elements.length; i++) {if (ctx._source.elements[i].SerialNumber == params.sn) { ctx._source.elements[i] = params.newElement; }}";

    String json = "{\"OUI\":\"00D09E\", \"SerialNumber\":\"NEW00000001AB\"}";
    Map<String, Object> jsonMap = new ObjectMapper().readValue(json, HashMap.class);
    Map<String, Object> params = ImmutableMap.of(
    	"sn", "00000001AA"
    	"newElement", jsonMap);

    UpdateRequest request = new UpdateRequest().index("PlayerIndex").id("1");
                request.script(new Script(ScriptType.INLINE,
                        "painless",
                        updateElementScript,   
                        params));

    client.update(request, RequestOptions.DEFAULT);    // RestHighLevelClient

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.