Search code examples
elasticsearchelasticsearch-painless

Painless Unable to access Array within an object


I am trying to access an array object within the source in the painless script but I am not able to with the error

"failed_shards" : [
      {
        "shard" : 0,
        "index" : "boxIndex",
        "node" : "gsbkERMmT72w3IV4SwuIDw",
        "reason" : {
          "type" : "script_exception",
          "reason" : "runtime error",
          "script_stack" : [
            "if (params._source.boxArray[0].boxName =="red"){\n                        ",
            "                  ^---- HERE"
          ],
          "script" : " ...",
          "lang" : "painless",
          "position" : {
            "offset" : 41,
            "start" : 23,
            "end" : 105
          },
          "caused_by" : {
            "type" : "null_pointer_exception",
            "reason" : "Cannot invoke \"Object.getClass()\" because \"callArgs[0]\" is null"
          }
        }
      }
    ]

My Request is

GET /boxIndex/_search
{
   "query":{
      "bool":{
         "must":{
            "script":{
               "script":{
                  "lang":"painless",
                  "source": """
                      if (params._source.boxArray[0].boxName == "red"){
                        return true;
                      }
return false;
                """
               }
            }
         }
      }
   }
}

The Object is stored as

"_source": { "boxArray": [{ "boxName": "red" }] }

I am not able to figure out as the ES documentation seems to be stating that its should work: https://www.elastic.co/guide/en/elasticsearch/reference/master/modules-scripting-fields.html. I cant use doc object as the documentation states:

Doc-values can only return "simple" field values like numbers, dates, geo- points, terms, etc, or arrays of these values if the field is multi-valued. It cannot return JSON objects.

Is there a way to access json object and array within the painless script? Am I missing something here?


Solution

  • A script query can only access doc values, so your script will work if you change it to this.

    if (doc['boxArray.boxName.keyword'].get(0) == "red"){
        return true;
    }
    return false;
    

    However, in arrays of non-nested data, the order of the doc values list might not be the same as the one you have in your source document, so your mileage may vary here.