Bond
Bond

Reputation: 53

ElasticSearch : Appending object in existing array of object Field

My field mapping:

"Pincode": {

    "analyzer": "standard",
    "type": "string"

},
    "Residence_address": {

        "include_in_parent": true,


           "type": "nested",
            "properties": {
                "address": {
                    "analyzer": "standard",
                    "type": "string"
                },
                "Address_type": {
                    "analyzer": "standard",
                    "type": "string"
                },
                "Pincode": {
                    "analyzer": "standard",
                    "type": "string"
                }
            }

        }

i have data :

    "Residence_address": [

        {
            "address": "safadfsdf",
            "Address_type": "Owned",
            "Pincode": "50005756768674"
        }
        ,
        {
            "address": "Collage of lkj",
            "Address_type": "Rented",
            "Pincode": "419005"
        }

    ],
"Pincode": [

    "11" ,"12"

]

when i insert pincode :

  "Pincode": ["15"] 

its working fine . For normal array fields(Not array of objects) the appending works fine.

but when I want to insert object as :

 "Residence_address": [
                    {
                     "address": "abbbbbb",
                     "Address_type": "bcccccc",
                     "Pincode": "67999999"
                  }
               ]

When i insert it using this code :

      updateRequest.script("ctx._source.Residence_address +=  ADD");
          JSONArray Address = (JSONArray) temp.get("Residence_address");              
          i = 0;
          while(i < Address.size()){
                  System.out.println(Address.get(i).toString());
                  updateRequest.addScriptParam("ADD", Address.get(i++).toString());
               }

it gives me error :

org.elasticsearch.index.mapper.MapperParsingException: object mapping [Residence_address] trying to serialize a value with no field associated with it, current value [{"address":"abbbbbb","Address_type":"bcccccc","Pincode":"67999999"}]
    at org.elasticsearch.index.mapper.object.ObjectMapper.serializeValue(ObjectMapper.java:702)
    at org.elasticsearch.index.mapper.object.ObjectMapper.parse(ObjectMapper.java:497)
    at org.elasticsearch.index.mapper.object.ObjectMapper.serializeValue(ObjectMapper.java:706)
    at org.elasticsearch.index.mapper.object.ObjectMapper.serializeNonDynamicArray(ObjectMapper.java:695)
    at org.elasticsearch.index.mapper.object.ObjectMapper.serializeArray(ObjectMapper.java:604)
    at org.elasticsearch.index.mapper.object.ObjectMapper.parse(ObjectMapper.java:489)
    at org.elasticsearch.index.mapper.DocumentMapper.parse(DocumentMapper.java:544)
    at org.elasticsearch.index.mapper.DocumentMapper.parse(DocumentMapper.java:493)
    at org.elasticsearch.index.shard.IndexShard.prepareIndex(IndexShard.java:493)
    at org.elasticsearch.action.index.TransportIndexAction.shardOperationOnPrimary(TransportIndexAction.java:192)
    at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$PrimaryPhase.performOnPrimary(TransportShardReplicationOperationAction.java:574)
    at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$PrimaryPhase.routeRequestOrPerformLocally(TransportShardReplicationOperationAction.java:444)
    at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$PrimaryPhase.doRun(TransportShardReplicationOperationAction.java:370)
    at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:36)
    at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction.doExecute(TransportShardReplicationOperationAction.java:112)
    at org.elasticsearch.action.index.TransportIndexAction.innerExecute(TransportIndexAction.java:136)
    at org.elasticsearch.action.index.TransportIndexAction.doExecute(TransportIndexAction.java:114)
    at org.elasticsearch.action.index.TransportIndexAction.doExecute(TransportIndexAction.java:63)
    at org.elasticsearch.action.support.TransportAction.execute(TransportAction.java:75)
    at org.elasticsearch.action.update.TransportUpdateAction.shardOperation(TransportUpdateAction.java:217)
    at org.elasticsearch.action.update.TransportUpdateAction.shardOperation(TransportUpdateAction.java:170)
    at org.elasticsearch.action.support.single.instance.TransportInstanceSingleOperationAction$AsyncSingleAction$1.run(TransportInstanceSingleOperationAction.java:187)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

help please.

Upvotes: 2

Views: 3404

Answers (1)

Val
Val

Reputation: 217504

If you have several addresses in Address, you add many parameters with the same parameter name ADD, which will not work.

Try this instead:

      String newAddrs = "";
      JSONArray Address = (JSONArray) temp.get("Residence_address");              
      int i = 0;
      while(i < Address.size()){
              newAddrs += "ADD" + i + ( i < Address.size() - 1 ? "," : "");
              updateRequest.addScriptParam("ADD"+i, Address.get(i++));
      }
      updateRequest.script("ctx._source.Residence_address += ["+newAddrs+"]");

So if you have 3 addresses, you will end up with a script that looks like:

ctx._source.Residence_address += [ ADD0, ADD1, ADD2 ]

And you will have three script parameters named ADD0, ADD1, ADD2

Upvotes: 2

Related Questions