Adding objects to an Array filed in Elastic Search index using Java High level Rest Client

I am trying to add a list or a single object to a Array field on a Elastic Search Index, the index is as shown below:

    "_index" : "class_index",
        "_id" : "1234",
        "_source" : {
          "externalId" : 1234,
          "description" : "10th grade",
          "users" : [
            {
              "name" : useer 1,
              "age" : "16",
              "active" : 1
            },
            {
              "name" : user 2,
              "age" : "15",
              "adtive" : 1
            }
          ]
        }

I am using Java High level Rest client to add a single object to the array field by conveting the object to a JsonNode. My Question is two part, is it possible to pass an Array of user objects instead of a single object? Also, I am running into an issue as shown below with this approach.

      //usere here is a java object 
       Map<String, Object> paramMap = new HashMap<>();
       ObjectMapper mapper = new ObjectMapper();
       //user object: {"name":user name,"agee":"25","active":0}

       JsonNode node = mapper.convertValue(userList.getUsers().get(0), JsonNode.class);
       Map<String, Object> jsonMap = mapper.convertValue(node, Map.class);
        
       final UpdateRequest indexRequest = new UpdateRequest(INDEX, TYPE, _id);

       Script inline = new Script(ScriptType.INLINE, "painless",
                "ctx._source.characters += params.user)", singletonMap("user", jsonMap));
        indexRequest.script(inline); 
        restClient.update(indexRequest, RequestOptions.DEFAULT);

I am not sure if I am missing something here but I still get the following exception trying to update the field with a single object:

    caused by: org.elasticsearch.ElasticsearchException: Elasticsearch exception [type=illegal_argument_exception, reason=unexpected token [')'] was expecting one of [{<EOF>, ';'}].]
        at org.elasticsearch.ElasticsearchException.innerFromXContent(ElasticsearchException.java:509) ~[elasticsearch-6.8.10.jar:6.8.10]
        at org.elasticsearch.ElasticsearchException.fromXContent(ElasticsearchException.java:420) ~[elasticsearch-6.8.10.jar:6.8.10]
        at org.elasticsearch.ElasticsearchException.innerFromXContent(ElasticsearchException.java:450) ~[elasticsearch-6.8.10.jar:6.8.10]

Can we achieve the goal without using a script?

That'd be definitely better.
The main question is why do you want to use the Update API instead of the Index API?

Provide the full object instead of try to update some parts of it.

So the problem is that we are only getting the new user list , users which have been added in the past hour. If we have to build the full document, we need to fetch all the users associated with the class and merge them with the the newly added ones.

What is the use case?

Why not adding individual users instead as separated documents?
I'd probably go that way.

Use case is to update a specifc array filed with in a Document. Individual user objects here are the elements I would like to update in the array. I believe it can be done using the script as shown in the code, but I might be missing something with respect to how I am building the json map.

That's not a use case IMO. That's a technical implementation of a use case but not the use case as per say.

I'd not spend time on solving a problem in the wrong way so that's why I'm asking about the use case:

  • what type of objects people will be searching for?
  • on which fields do they need to query?
  • what kind of resultset are you looking for?

Sorry for the confusion, may be the data I used here as an example is not very intuitive. My question was not directed towards search but was more about how nested data can be updated using the java High level rest client. But to clarity, the search will be based on the "description" or "id" of the document which will return all the users associated with the class.
Having said that, I need to update the document (partial update) by adding new users to the "users" filed which is an Array object. My question is directed towards the code below:

final UpdateRequest indexRequest = new UpdateRequest("class_index", _id);
Script inline = new Script(ScriptType.INLINE, "painless",
                "ctx._source.characters += params.user)", singletonMap("user", jsonMap));
 indexRequest.script(inline); 
        restClient.update(indexRequest, RequestOptions.DEFAULT);

I get an exception when I run this code and am not sure what I am missing here. And the other question I had was if we have an alternative to updating a document filed without using Painless script.

Thank you!

Why?

Again, that's a bit counter intuitive when you deal with search engines. That's the reason, I'm asking you questions about the use case. Probably someone can give you the answer to the question you asked, but this might be a good answer to a bad question.

I'm not experimented in painless so I can't really help more. If you want to continue on exploring this nested update thing, I'd recommend to provide a full recreation script as described in About the Elasticsearch category. It will help to better understand what you are doing. Please, try to keep the example as simple as possible.

A full reproduction script is something anyone can copy and paste in Kibana dev console, click on the run button to reproduce your use case. It will help readers to understand, reproduce and if needed fix your problem. It will also most likely help to get a faster answer.

So don't even think of using Java code first. Once the solution is found in pure Elasticsearch/Kibana script, we can help if needed to move to Java code but that should be straight forward.

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