Elasticsearch:如何返回字段中具有最高值的所有文档?

时间:2018-03-06 07:37:33

标签: elasticsearch

我是Elasticsearch的新手,我目前在一个相当基本的问题上遇到了一些困难。假设我有以下映射:

PUT /myindex/_mappings/people 
{
    "properties": {
        "name": {"type": "keyword"},
        "age" : {"type": "integer"},
    }
}

以下文件:

{"name": "Bob", "age": 20},
{"name": "Ben", "age": 25},
{"name": "Eli", "age": 30},
{"name": "Eva", "age": 20},
{"name": "Jan", "age": 21},
{"name": "Jim", "age": 20},
{"name": "Lea", "age": 30},

如何创建单个查询,返回索引中最旧的所有人?换句话说,我期待Eli和Lea被退回,因为他们都是30岁,比其他人都年长。

我正在使用Elasticsearch API 6.0.0 for javascript(我的应用程序是用nodejs编写的)。现在,我的解决方法是对数据库执行2个请求。第一种是聚合最大年龄(应该返回30),然后使用这个最大年龄来执行另一个请求:

GET /myindex/people/_search
{
    "aggs": {
        "max_age": {"max": {"field": "age"}}
    }
}

GET /myindex/people/_search
{
    "query": {"term": {"age": <max_age>}} // where <max_age> should be 30
}

显然,这是非常低效的。你能帮我制定一个完成所有这一切的查询吗?

困难的是我事先并不知道有多少文件具有最高价值,这意味着我无法使用&#34;尺寸&#34;这里提到的方法&#34; Single query to find document with largest value for some field&#34;

提前致谢!

1 个答案:

答案 0 :(得分:0)

您可以像这样结合termstop_hits聚合

GET /myindex/people/_search
{
  "size": 0,
  "aggs": {
    "group_by_age": {
      "terms": {
        "field": "age",
        "order": {
          "_term": "desc"
        },
        "size": 1
      },
      "aggs": {
        "oldest_people": {
          "top_hits": {
            "from": 0,
            "size": 9000
          }
        }
      }
    }
  }
}

请注意"order": { "_term": "desc" }"size": 1仅返回最大年龄为terms聚合的存储分区。然后我们只列出top_hits的第一个9000(或任意数字)文档。