Elasticsearch——Bucket聚合查询

Bucket聚合查询

Posted by John Doe on 2023-11-10
Words 1.3k and Reading Time 6 Minutes
Viewed Times

概念

Bucket 可以理解为一个桶,它会遍历文档中的内容,凡是符合某一要求的就放入一个桶中,分桶相当与 SQL 中的 group by

这篇博客讲的桶的关键字有:Terms AggregationFilter AggregationHistogram AggregationRange AggregationDate Aggregation

一、创建索引、数据

1、创建索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
DELETE cars
PUT cars
{
"mappings": {
"properties": {
"price": {
"type":"long"
},
"color": {
"type":"keyword"
},
"brand": {
"type":"keyword"
},
"sellTime": {
"type":"date"
}
}
}
}

属性字段:价格、颜色、品牌、销售时间

2、添加索引数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST /cars/_bulk
{ "index": {}}
{ "price" : 80000, "color" : "red", "brand" : "BMW", "sellTime" : "2014-01-28" }
{ "index": {}}
{ "price" : 85000, "color" : "green", "brand" : "BMW", "sellTime" : "2014-02-05" }
{ "index": {}}
{ "price" : 120000, "color" : "green", "brand" : "Mercedes", "sellTime" : "2014-03-18" }
{ "index": {}}
{ "price" : 105000, "color" : "blue", "brand" : "Mercedes", "sellTime" : "2014-04-02" }
{ "index": {}}
{ "price" : 72000, "color" : "green", "brand" : "Audi", "sellTime" : "2014-05-19" }
{ "index": {}}
{ "price" : 60000, "color" : "red", "brand" : "Audi", "sellTime" : "2014-06-05" }
{ "index": {}}
{ "price" : 40000, "color" : "red", "brand" : "Audi", "sellTime" : "2014-07-01" }
{ "index": {}}
{ "price" : 35000, "color" : "blue", "brand" : "Honda", "sellTime" : "2014-08-12" }

3、查看是否成功

命令

1
GET /_cat/count/cars?v

可以看到该索引存在,并且有8条文档数据。

es

二、Terms Aggregation

官方7.3文档Terms Aggregation

概念 : 根据某一项的每个唯一的值的聚合。

1、根据品牌分桶

1
2
3
4
5
6
7
8
GET cars/_search?size=0
{
"aggs" : {
"genres" : {
"terms" : { "field" : "brand" }
}
}
}

返回结果

es

2、分桶后只显示文档数量前3的桶

1
2
3
4
5
6
7
8
9
10
11
GET cars/_search?size=0
{
"aggs" : {
"cars" : {
"terms" : {
"field" : "brand",
"size" : 3
}
}
}
}

返回

es

从图中可以看出文档数量前三的桶。

3、分桶后排序

1
2
3
4
5
6
7
8
9
10
11
GET cars/_search?size=0
{
"aggs" : {
"genres" : {
"terms" : {
"field" : "brand",
"order" : { "_count" : "asc" }
}
}
}
}

4、显示文档数量大于3的桶

1
2
3
4
5
6
7
8
9
10
11
GET cars/_search?size=0
{
"aggs" : {
"brands" : {
"terms" : {
"field" : "brand",
"min_doc_count": 3
}
}
}
}

5、使用精确指定的词条进行分桶

1
2
3
4
5
6
7
8
9
10
11
GET /cars/_search?size=0
{
"aggs" : {
"JapaneseCars" : {
"terms" : {
"field" : "brand",
"include" : ["BMW", "Audi"]
}
}
}
}

这里也只展示些常用的,更多有关Terms Aggregation那就看官网吧。

三、 Filter Aggregation

官方文档Filter AggregationFilters Aggregation

Filter概念:指具体的域和具体的值,可以说是在 Terms Aggregation 的基础上进行了过滤,只对特定的值进行了聚合。

1、过滤获取品牌为BMW的桶,并求该桶平均值

1
2
3
4
5
6
7
8
9
10
11
GET /cars/_search?size=0
{
"aggs" : {
"brands" : {
"filter" : { "term": { "brand": "BMW" } },
"aggs" : {
"avg_price" : { "avg" : { "field" : "price" } }
}
}
}
}

返回

es

2、过滤获取品牌为BMW的或者color为绿色的桶

Filters概念 : Filter Aggreagtion 只能指定一个过滤条件,响应也只是单个桶。如果想要只对多个特定值进行聚合,使用 Filter Aggreagtion 只能进行多次请求。

而使用 Filters Aggreagation 就可以解决上述的问题,它可以指定多个过滤条件,也是说可以对多个特定值进行聚合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
GET /cars/_search?size=0
{
"size": 0,
"aggs" : {
"cars" : {
"filters" : {
"filters" : {
"colorBucket" : { "match" : { "color" : "red" }},
"brandBucket" : { "match" : { "brand" : "Audi" }}
}
}
}
}
}

返回

es

四、Histogram Aggreagtion

官方文档Histogram Aggreagtion

概念 Histogram与Terms聚合类似,都是数据分组,区别是Terms是按照Field的值分组,而Histogram可以按照指定的间隔对Field进行分组

1、根据价格区间为10000分桶

1
2
3
4
5
6
7
8
9
10
11
GET /cars/_search?size=0
{
"aggs" : {
"prices" : {
"histogram" : {
"field" : "price",
"interval" : 10000
}
}
}
}

返回

es

2、根据价格区间为10000分桶,同时如果桶中没有文档就不显示桶

上面的分桶我们可以发现价格在5000~6000 的文档没有也显示为0,我们想把如果桶中没有文档就不显示该桶

1
2
3
4
5
6
7
8
9
10
11
12
GET /cars/_search?size=0
{
"aggs" : {
"prices" : {
"histogram" : {
"field" : "price",
"interval" : 10000,
"min_doc_count" : 1
}
}
}
}

返回

es

五、Range Aggregation

官方文档Range Aggregation

概念: 根据用户传递的范围参数作为桶,进行相应的聚合。在同一个请求中,可以传递多组范围,每组范围作为一个桶。

1、根据价格区间分桶

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GET /cars/_search?size=0
{
"aggs" : {
"price_ranges" : {
"range" : {
"field" : "price",
"ranges" : [
{ "to" : 50000 },
{ "from" : 5000, "to" : 80000 },
{ "from" : 80000 }
]
}
}
}
}

返回

es

我们也可以指定key的名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GET /cars/_search?size=0
{
"aggs" : {
"price_ranges" : {
"range" : {
"field" : "price",
"ranges" : [
{ "key" : "xiaoyu", "to" : 50000 },
{ "key" : "baohan", "from" : 5000, "to" : 80000 },
{ "key" : "dayu", "from" : 80000 }
]
}
}
}
}

返回

es

六、 Date Aggregation

官方文档Date Histogram AggregationDate Range Aggregation

Date Histogram概念 针对于时间格式数据的直方图聚合,基本的特性与 Histogram Aggregation 一致。

1、按月分桶显示每个月的销量

注意 官方文档这里不是interval而是calendar_interval,但是按照这样操作会报错,因为我看的7.3的文档,而我部署的es是7.1版本。说明这个地方7.3有了改进。

1
2
3
4
5
6
7
8
9
10
11
12
POST /cars/_search?size=0
{
"aggs" : {
"sales_over_time" : {
"date_histogram" : {
"field" : "sellTime",
"interval" : "1M",
"format" : "yyyy-MM-dd"
}
}
}
}

返回

es

2、根据指定时间区间分桶

Date Range概念 :针对于时间格式数据的范围聚合,基本的特性与 Range Aggreagtion 一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /cars/_search?size=0
{
"aggs": {
"range": {
"date_range": {
"field": "sellTime",
"format": "MM-yyyy",
"ranges": [
{ "to": "now-10M/M" },
{ "from": "now-10M/M" }
]
}
}
}
}

上面的意思是10个月前的分为一个桶,10个月前之后的分为一个桶

es


This is copyright.

...

...

00:00
00:00