如何将Elasticsearch _msearch多查询改写为桶聚合单_search查询
问题原因
你写的聚合语句报错核心是两个用法错误:
bucket_sort属于管道聚合,作用是对父聚合输出的桶做排序、截断,不能和terms聚合平级放置,也不支持桶内文档的排序筛选- 没有定义桶内取文档的逻辑,直接写排序规则时ES无法识别排序目标,直接抛出语法错误
正确写法
要实现「每个车型分组下取time最新的1条记录」,用terms分桶聚合搭配top_hits子聚合即可,完全匹配你原_msearch的查询效果,单次_search请求就能完成。
仅查询红/黑/白三个指定车型
和你原msearch的查询范围完全一致的写法:
GET /index/_search { "size": 0, "query": { "terms": { "name.keyword": ["CAR_RED", "CAR_BLACK", "CAR_WHITE"] } }, "aggs": { "CARS": { "terms": { "field": "name.keyword", "size": 3 }, "aggs": { "latest_record": { "top_hits": { "size": 1, "sort": { "time": { "order": "desc" } } } } } } } }
查询所有CAR开头车型的最新记录
如果后续新增其他颜色车型不需要改查询,可以用前缀过滤匹配所有CAR开头的车型:
GET /index/_search { "size": 0, "query": { "prefix": { "name.keyword": "CAR_" } }, "aggs": { "CARS": { "terms": { "field": "name.keyword", "size": 100 }, "aggs": { "latest_record": { "top_hits": { "size": 1, "sort": { "time": { "order": "desc" } } } } } } } }
注意:terms聚合的size参数需要设置为大于等于你实际的车型总数,ES默认只返回前10个桶,数值不够会导致部分车型数据丢失。
结果取值说明
返回结果中aggregations.CARS.buckets数组的每一项对应一个车型,每个bucket下latest_record.hits.hits里的内容,就是该车型按time倒序的最新1条文档,和你原msearch每个子查询返回的文档结构完全一致。
内容的提问来源于stack exchange,提问作者user19494966
相关产品推荐
相关产品推荐

