【问题标题】:Elastic search aggregation with range query具有范围查询的弹性搜索聚合
【发布时间】:2016-03-15 19:00:53
【问题描述】:

我正在构建一个满足条件 >= avg 的 ES 查询。

这是一个例子:

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

我收到以下错误

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

我想知道我们如何在弹性查询中使用聚合值和范围查询

【问题讨论】:

    标签: elasticsearch querydsl sense


    【解决方案1】:

    您不能在查询中嵌入聚合。您需要先发送一个聚合查询以找出平均值,然后使用获得的平均值发送第二个范围查询。

    查询 1:

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

    然后你得到平均价格,说它是12.3 并在你的第二个查询中使用它,如下所示:

    查询 2:

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

    【讨论】:

    • 有没有办法在单个查询中完成?例如:在 SQL 世界中,我们使用以下查询在单个连接查询中查找平均工资员工。 "select * from employee e where e.salary >= ( select avg(salary) from Salary);" ..我正在寻找类似的东西。
    • 欢迎来到 NoSQL 世界 ;-)
    • 我使用 Python 以编程方式解决了它,因为我没有找到使用查询 DSL 的方法。
    • DSL 有一种方法:运行两个查询 :-)
    • 也许为了其他人的利益,您可以分享您如何实现这一点的亮点,即您当然必须以某种方式运行两个查询才能找到然后运行您的范围查询的平均价格。
    【解决方案2】:

    在我尝试使用不同的ES聚合如bucket selector后,我发现使用python可以完成。

    这是我为解决此问题而创建的 python 代码。 请注意:运行前需要填写 URL 、 USER_NAME 、 PASSWORD 。

    #! /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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-31
      • 2014-09-25
      • 2015-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-24
      • 1970-01-01
      相关资源
      最近更新 更多