第三阶段 20 · metric 指标聚合

第三阶段 20 · metric 指标聚合
20 · metric 指标聚合阶段第三阶段 / 聚合能力ESsum/avg/min/max/value_count/cardinality| PostgreSQLSUM/AVG/MIN/MAX/COUNT/COUNT(DISTINCT)1. 概念指标聚合metric aggregation对一批文档算出一个数值相当于 SQL 里不带GROUP BY的聚合函数。ES 聚合SQL 函数sumSUM()avgAVG()min/maxMIN()/MAX()value_countCOUNT(col)cardinalityCOUNT(DISTINCT col)近似stats一次返回 count/min/max/avg/sum2. PostgreSQL 对照SELECTSUM(net_amount)AStotal_amount,AVG(net_amount)ASavg_amount,MAX(net_amount)ASmax_amount,COUNT(*)AScnt,COUNT(DISTINCTmaterial)ASmaterial_kindsFROMsalesdataWHEREgeo_cdAP;3. ES DSL聚合结果和命中文档是分开返回的。通常把size设 0不要文档只要聚合GET salesdata_idx/_search { size: 0, query: { term: { geo_cd: AP } }, aggs: { total_amount: { sum: { field: net_amount } }, avg_amount: { avg: { field: net_amount } }, max_amount: { max: { field: net_amount } }, material_kinds: { cardinality: { field: material } } } }或一次拿全套统计aggs: { amount_stats: { stats: { field: net_amount } } }4. Spring Boot 实现ComponentpublicclassDoc20MetricAgg{AutowiredprivateElasticsearchClientelasticsearchClient;/** SUM(net_amount) WHERE geo_cd ? */publicdoublesumAmount(StringindexName,StringgeoCd)throwsIOException{SearchResponseVoidrespelasticsearchClient.search(s-s.index(indexName).size(0)// 不要文档.query(q-q.term(t-t.field(geo_cd).value(geoCd))).aggregations(total_amount,a-a.sum(su-su.field(net_amount))),Void.class);returnresp.aggregations().get(total_amount).sum().value();}/** COUNT(DISTINCT material) */publiclongdistinctMaterials(StringindexName)throwsIOException{SearchResponseVoidrespelasticsearchClient.search(s-s.index(indexName).size(0).aggregations(material_kinds,a-a.cardinality(c-c.field(material))),Void.class);returnresp.aggregations().get(material_kinds).cardinality().value();}}读取结果时按聚合类型取值.sum().value()、.avg().value()、.cardinality().value()、.max().value()等。5. 坑与最佳实践size: 0只要聚合别要文档省带宽。忘了写会白白返回一堆命中文档。对text字段聚合报错要对keyword或数值聚合字符串用field.keyword。cardinality是近似值基于 HyperLogLog海量去重会有小误差可调precision_threshold。数值精度sum大量浮点累加可能有精度问题金额敏感可用scaled_float或整数分。聚合前先过滤query缩小范围能显著提升聚合性能。下一篇21-terms-分组聚合.md。