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

3

我是一个 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编写的)。目前,我的解决方法是执行两个请求到数据库。第一个请求是聚合最大年龄(应返回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
}

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

困难之处在于,我事先不知道有多少个具有最高值的文档,这意味着我不能使用此处提到的 “size” 方法 "Single query to find document with largest value for some field"

提前感谢!

1个回答

5
您可以像这样组合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
          }
        }
      }
    }
  }
}

注意当我们使用聚合函数terms时,可以通过添加参数"order": { "_term": "desc" }"size": 1来仅返回具有最大年龄的桶,然后我们可以通过top_hits列出前9000(或任意数量)篇文档。


应标记为接受的值。非常感谢。顺便说一下,我不能在聚合大小中放置超过100个,9000会返回一个错误===>顶部命中结果窗口太大,顶部命中聚合器[latest_results]的from + size必须小于或等于:[100]但是是[9000]。可以通过更改[index.max_inner_result_window]索引级别设置来设置此限制。显然,这与索引配置有关。 - Deunz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接