Search code examples
elasticsearchkibanaelasticsearch-painless

Get result from aggs in script ElasticSearch/Painless


I'm new in ElasticSearch world. I've been trying write simple request and I need to get aggs result in my script to make simple condition. Is it possible to do it in this way? The condition below is only for example.

GET _search
{
  "aggs" : {
      "sum_field" : { "sum" : { "field" : "someField" } }
  },
  "script_fields": {
    "script_name": {
      "script": {
        "lang": "painless",
        "source": """
             // get there aggs result (sum_field)
              if(sum_field > 5){
                  return sum_field
              }
        """
      }
    }
  }
}

Solution

  • The requirement is to execute sum aggregation over multiple indexes having the same field name

    Now with multiple indexes, you'll have to check if that particular field exists in that indexes or not AND if the field is of the same datatype.

    Indexes

    I've created three indexes, having a single field called num.

    index_1
         - num: long
    
    index_2
         - num: long
    
    index_3
         - num: text
              : fielddata: true
    

    Also notice how if the field is of type text, then I've set its property fielddata:true. But if you do not set it, then the below query would give you aggregation result as well as an error saying you cannot retrieve the value of type text as its an analyzed string and you can only use doc for fields which are non_analyzed.

    Sample Query:

    POST /_search
    {  
       "size":0,
       "query":{  
          "bool":{  
             "filter":[  
                {  
                   "exists":{  
                      "field":"num"
                   }
                }
             ]
          }
       },
       "aggs":{  
          "myaggs":{  
             "sum":{  
                "script":{  
                   "source":"if(doc['num'].value instanceof long) return doc['num'].value;"
                }
             }
          }
       }
    }
    

    Query if you cannot set fielddata:true

    In that case, you need to explicitly mention the indexes on which you'd want to aggregate.

    POST /_search
    {  
       "size":0,
       "query":{  
          "bool":{  
             "filter":[  
                {  
                   "exists":{  
                      "field":"num"
                   }
                },
                {  
                   "terms":{  
                      "_index":[  
                         "index_1",
                         "index_2"
                      ]
                   }
                }
             ]
          }
       },
       "aggs":{  
          "myaggs":{  
             "sum":{  
                "script":{  
                   "source":"if(doc['num'].value instanceof long) return doc['num'].value;"
                }
             }
          }
       }
    }
    

    Hope this helps!