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?