Elastic search aggregation with range query

心已入冬 提交于 2019-12-12 03:29:57

问题


I am working to build a ES query that satisfies the condition >= avg .

Here is an example:

GET /_search
{
    "size" : 0,
    "query" : {
        "filtered": {
            "filter": {
                "range": {
                    "price": {
                        "gte": {
                          "aggs" : {
                            "single_avg_price": {
                                "avg" :{ 
                                  "field" : "price" 
                                }
                              }
                            }
                          }
                }
            }
        }
    }
    }
}

I get the following error

"type": "query_parsing_exception",
"reason": "[range] query does not support [aggs]",

I wonder how do we use aggregated value with range query in Elastic query


回答1:


You cannot embed aggregations inside a query. You need to first send an aggregation query to find out the average and then send a second range query using the obtained average value.

Query 1:

POST /_search
{
  "size": 0,
  "aggs": {
    "single_avg_price": {
      "avg": {
        "field": "price"
      }
    }
  }
}

Then you get the average price, say it was 12.3 and use it in your second query, like this:

Query 2:

POST /_search
{
  "size": 10,
  "query": {
    "filtered": {
      "filter": {
        "range": {
          "price": {
            "gte": 12.3
          }
        }
      }
    }
  }
}



回答2:


After I tried using different ES aggregations such as bucket selector , I found that it can be done using python.

Here is the python code I created to solve this issue. Please note: URL , USER_NAME , PASSWORD needs to be filled before run it.

#! /usr/bin/python
import sys,json,requests
from requests.auth import HTTPBasicAuth

# static variables
URL=''
USER_NAME=''
PASSWORD=''

# returns avg value 
def getAvg():
    query = json.dumps({
        "aggs": {
            "single_avg_price": {
              "avg": {
                "field": "price"
              }
            }
         }
    })
    response = requests.get(URL,auth=HTTPBasicAuth(USER_NAME,PASSWORD), data=query)
    results = json.loads(response.text)
    return results['aggregations']['single_avg_price']['value']

#returns rows that are greater than avg value 
def rows_greater_than_avg(avg_value):
    query = json.dumps({
     "query" : {
        "range": {
            "price": {
                "gte":avg_value
              }
         }
      }
    })
    response = requests.get(URL,auth=HTTPBasicAuth(USER_NAME,PASSWORD), data=query)
    results = json.loads(response.text)
    return results

# main method
def main():
   avg_value = getAvg()
   print( rows_greater_than_avg(avg_value))

main()


来源:https://stackoverflow.com/questions/36019873/elastic-search-aggregation-with-range-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!