北京市城乡建设和交通委员会网站培训学校招生营销方案
一、关于
- 1、说明
在 ElasticSearch 中,基于索引和检索的基础上,提供了聚合(Aggregations)的功能,对存储的数据进行统计和分析
在 ElasticSearch 中,将聚合分为 指标聚合(Metric)、存储桶聚合(Bucket)、管道聚合(Pipeline)三类
参考:Aggregations | Elasticsearch Guide [8.0] | Elastic
- 2、语法
在查询(_search)的请求体中,以 aggregations 为节点,并按如下的语法来定义
{"aggregations" : { <!-- 聚合节点,固定的格式,使用 aggregations 或 aggs 命名 -->"<aggregation_name>" : { <!-- 聚合的名字,自定义,比如 aggs-max 等 -->"<aggregation_type>" : { <!-- 聚合的类型,例如 avg、range 等 --><aggregation_body> <!-- 聚合体:对哪些字段进行聚合 -->}[,"meta" : { [<meta_data_body>] } ]? <!-- 元数据,在结果里原样返回 -->[,"aggregations" : { [<sub_aggregation>]+ } ]? <!-- 在聚合里面再定义的子聚合 -->}[,"<aggregation_name_2>" : { ... } ]* <!-- 其他聚合的名字 -->}
}
- 3、补充
默认情况下,包含聚合的搜索会同时返回搜索结果和聚合结果。若仅要返回聚合结果,请设置 size 为 0
默认情况下,操作字段没有值的文档将被忽略,但是也可以为它们定义具体值,通过 missing 参数指定
二、示例
- 1、指标聚合
对一个数据集执行类似SQL中的最大(max)、最小(min)、求和(sum)、求平均(avg)等操作的聚合
基础聚合
{"aggs": {// 求所有文档的指定字段的平均值"aggs_price_avg": {"avg": {"field": "price"}}}
}
优化返回
GET /goods/_search
{"aggs": {"aggs-avg": {"avg": {"field": "price",// 为没有该值的文档指定默认值"missing": 0}}},// 不返回搜索结果"size": 0
}
搜索聚合
GET /goods/_search
{"aggs": {// 根据指定字段分桶"group_type_bucket": {"terms": {"field": "classifyId"}}}
}
范围聚合
GET /goods/_search
{// 先条件查询筛选范围"query": {"match": {"name": "冰淇淋"}},"aggs": {// 再在范围内求指定字段的平均值"aggs-avg": {"avg": {"field": "pPrice"}}}
}
多聚合
GET /goods/_search
{"aggs": {// 聚合一:求平均"aggs-avg": {"avg": {"field": "price"}},// 聚合二:求总和"aggs-sum": {"sum": {"field": "stock"}}}
}
嵌套聚合
GET /goods/_search
{"aggs": {// 先根据指定字段分组到不同的桶"group_by_type": {"terms": {"field": "typeId"},// 再计算每个组的指定字段的平均值"aggs": {"group_avg_price": {"avg": {"field": "price"}}}}}
}
- 2、存储桶聚合
对一个数据集执行类似SQL中的分组(group by)操作类似。将匹配桶条件的文档 "落入" 该存储桶,并在整个聚合结束后返回一个桶列表
基础直方图
构建以指定字段且指定间隔的直方图;以四舍五入的规则将文档落在靠近的存储桶中
GET /goods/_search
{"aggs": {"buckets_price_histogram": {// 指定以价格字段且指定以每50为间隔建立直方图;四舍五入进入桶中"histogram": {"field": "price","interval": 50}}},"size": 0
}
日期直方图
类似于基础的直方图,但只能用于日期或日期范围的字段的值;仍然以四舍五入的规则将文档落在靠近的日期存储桶中
日历间隔(calendar_interval)
使用日历单位为间隔,且只接受一个单位的间隔单位;不同的单位比如月可能会有偏离,比如1月和2月的时长不一样
可以接受的单位包括:分钟(minute,1m)、小时(hour,1h)、一天(day,1d)、一周(week,1w)、一月(month,1M)、一季(quarter,1q)、一年(year,1y)
GET /goods/_search
{"aggs": {"sales_over_time": {"date_histogram": {"field": "addTime",// 以月份为间隔"calendar_interval": "month"}}},"size": 0
}
固定间隔(fixed_interval)
使用以指定数量的以秒为基础的间隔单位;永远不会有偏离,比如1秒永远等于1000毫秒
可以接受的单位包括:毫秒(ms)、秒(s)、分钟(m)、小时(h)、天(d)
GET /goods/_search
{"aggs": {"sales_over_time": {"date_histogram": {"field": "addTime",// 固定30天的间隔"fixed_interval": "30d"}}},"size": 0
}
自动间隔日期直方图
类似于日期直方图,指定一个期望的桶的目标数量,自动的选择桶的间隔以最佳地实现该目标
通过 buckets 指定期望桶数量,返回的桶数总是小于或等于这个目标数
GET /goods/_search
{"aggs": {"sales_over_time": {"auto_date_histogram": {"field": "addTime",// 期望最大返回10个桶"buckets": 10,// 格式化 key_as_string 的显示"format": "yyyy/MM/dd",// 字段为空默认的日期"missing": "2000/01/01"}}},"size": 0
}
范围区间桶聚合
使用用户定义的基于指定字段的一组范围(每个范围表示一个桶)而生成的多桶聚合
每个聚合桶包含范围的from值并排除to值
GET /goods/_search
{"aggs": {"price_ranges": {"range": {"field": "price",// 为每个桶关联一个唯一的字符串键,并以键值对的形式返回,而不是默认的数组"keyed": true,// 定义范围组"ranges": [// 价格小于100的组{ "to": 100.0 },// 价格从100到200的组{ "from": 100.0, "to": 200.0 },// 价格大于200的组{ "from": 200.0 }]}}},"size": 0
}
字段值分组桶
根据指定的字段,为每个字段的值,都构建一个桶
默认情况下,不支持全文检索(text)字段;默认情况下,只返回桶数量(doc_count)排名前十的存储桶
GET /goods/_search
{"aggs": {"genres": {"terms": {// 根据类型分组构建存储桶"field": "classifyId",// 自定义返回桶的数量"size": 5}}},"size": 0
}
- 3、管道聚合
不直接面向文档集的聚合,而是基于其他聚合的输出做二次处理的聚合。管道聚合不能具有子聚合,但是可以通过 buckets_path 链接另一个管道
管道聚合之聚合桶平均
兄弟级的管道聚合,用于计算在同级聚合中指定指标的(平均值)平均值
其他如:聚合桶总和(sum_bucket)、聚合桶最大值(max_bucket)、聚合桶最小值(min_bucket)、聚合桶同级(stats_bucket)也类似
GET /order/_search
{"aggs": {// 订单按月份的日期直方图的聚合"order_month_histogram": {"date_histogram": {"field": "addTime","calendar_interval": "month"},"aggs": {// 子聚合统计每月订单的总金额"price_total": {"sum": {"field": "price"}}}},// 直方图聚合的同级管道聚合"month_avg_price": {// 聚合的平均管道聚合,计算每月订单总金额的平均总金额"avg_bucket": {// 指定这个聚合的数据源:来自订单日期直方图聚合中的总金额聚合"buckets_path": "order_month_histogram > price_total"}}},"size": 0
}
管道聚合之聚合桶排序
父子级的管道聚合,用于对父级的多桶聚合的结果按照指定的一个或多个字段进行排序和截取
注意:想对桶内元素数量排序,需指定 _count 字段,而非显示的 doc_count 字段
GET /order/_search
{"aggs": {// 订单按月份的日期直方图的聚合"order_month_histogram": {"date_histogram": {"field": "addTime","calendar_interval": "month"},"aggs": {// 子聚合统计出每个月的订单的总金额(数据存储于对应的桶内)"price_total": {"sum": {"field": "price"}},// 对子聚合结果的多个桶进行排序操作"price_total_bucket_sort": {"bucket_sort": {// 排序规则(可选 即可以不排序直接通过 from / size 进行截取)"sort": [{// 按照订单总金额进行降序排序"price_total": {"order": "desc"}}],// 且过截断过滤掉第1条"from": 1,// 且只取过滤后的前3条"size": 3}}}}},"size": 0
}
管道聚合之聚合桶脚本
父子级的管道聚合,用于对父级的多桶聚合的结果,按照指定的脚本为每个桶进行指定的指标的计算
指定的指标必须为数字,且脚本也必须返回为数字
GET /order/_search
{"aggs": {// 订单按月份的日期直方图的聚合"order_month_histogram": {"date_histogram": {"field": "addTime","calendar_interval": "month"},// 子聚合"aggs": {// 子聚合第一个查询"price_total": {// 统计出每个月的订单的总金额(数据存储于对应的桶内)"sum": {"field": "price"}},// 子聚合第二个查询"source_app": {// 先过滤出来源为app的订单"filter": {"term": {"source_mark": "app"}},// 再针对过滤出的来源为app的数据继续聚合"aggs": {"source_app_price_total": {// 统计该来源的订单的总金额"sum": {"field": "price"}}}},// 计算每月订单中,来源为app的订单的总金额占当前月的总金额的百分比"source_app_percentage": {"bucket_script": {// 定义脚本需要的变量和变量的数据源"buckets_path": {"appSrcPriceTotal": "source_app > source_app_price_total","totalPriceTotal": "price_total"},// 要指定的脚本"script": "params.appSrcPriceTotal / params.totalPriceTotal * 100"}}}}},"size": 0
}