如何在单次Elasticsearch请求中统计每个字段的聚合词条总数?
如何在单次Elasticsearch请求中统计每个字段的聚合词条总数?
当然可以实现!你完全不用分开发多个请求,咱们把需要的聚合逻辑都塞进同一个请求里就行,既省时间又高效。
1. 同时获取单个字段的词条列表+总数
你之前分别做了play_name的terms聚合(拿到所有剧目列表)和cardinality聚合(拿到剧目总数),现在把这两个聚合放到同一个请求里就搞定了:
GET /shakespeare/_search { "size": 0, // 不需要返回具体文档,只保留聚合结果,减少数据量 "aggs": { // 保留你原来的剧目列表聚合 "plays_list": { "terms": { "field": "play_name", "order": { "_key": "asc" }, "size": 200 } }, // 新增剧目总数的基数统计 "total_plays_count": { "cardinality": { "field": "play_name" } } } }
这样响应里会同时返回所有剧目的列表,以及剧目的总数量,一次请求搞定两个需求。
2. 一次性统计多个字段的词条总数
如果想同时统计多个字段(比如play_name、speaker、line_id)的词条总数,只需要在aggs里多定义几个cardinality聚合就行:
GET /shakespeare/_search { "size": 0, "aggs": { "total_plays": { "cardinality": { "field": "play_name" } }, "total_speakers": { "cardinality": { "field": "speaker" } }, "total_unique_lines": { "cardinality": { "field": "line_id" } } } }
一些要注意的细节
- 关于
size:0:这个参数很重要,它告诉Elasticsearch不用返回匹配的具体文档,只返回聚合结果,能大幅减少响应的大小,提升请求速度。 - 字段类型限制:如果是text类型的字段,直接做terms或cardinality聚合会报错,需要用它的keyword子字段(比如
play_name.keyword,如果mapping里定义了的话),或者开启fielddata(不推荐,会占用大量内存)。从你之前的请求能正常运行来看,play_name应该是keyword类型或者有对应的keyword子字段。 - 基数统计的精度:cardinality聚合是近似统计,默认有2%左右的误差。如果需要更精确的结果,可以调整
precision_threshold参数,比如:
阈值越高,统计越精确,但内存消耗也会越大。"cardinality": { "field": "play_name", "precision_threshold": 1000 }
备注:内容来源于stack exchange,提问作者Eduard Florinescu
相关产品推荐
相关产品推荐

