Search code examples
arrayselasticsearchelasticsearch-painless

Retrieve information of last element of an array painless-ly in elasticsearch


While updating a doc (using update API), I need to extract a field of last entered element of an array, and then use it while adding a new element to the same array.

For example:

{
  "_id": "guid",
  "timestamp": "time",
  "conversation": [
    {
      "previousTopic": "A",
      "currentTopic": "B",
      "score": 80
    },
    {
      "previousTopic": "B",
      "currentTopic": "C",
      "score": 85
    }
  ]
}

Now, while inserting a new element to this array using the update API, first extract the "currentTopic" field of the last element (which is C in this case) and then insert this as "previousTopic" of the next element.

I know how to use basic update API which would insert a new element to the array of the document:

POST test/_doc/{doc_id}/_update
{
    "script" : {
        "source": "ctx._source.communication.add(params.newcom)",
        "lang": "painless",
        "params" : {
          "newcomm" : {
          "previousTopic": {extracted value will go here}
          "currentTopic" : "D"
          "score" : 89 }
        }
    }
}


Solution

  • I was able to do this flawlessly using painless scripting.

    POST test/_doc/nbsadmnsabdmas/_update
    {
        "script" : {
            "lang": "painless",
            "source" : 
            """
            // find the length of array 
            def count = ctx._source.conversation.length;
    
            // get to the last element and extract
            def temp = ctx._source.conversation[count-1].currentTopic;
    
            // add a new element to the array
            ctx._source.communication.add(['previousTopic':temp,'currentTopic':'D',
             'score':90]);
    
            """
        }
    }