聚合查詢(Bucket聚合)
上一篇講了Elasticsearch聚合查詢中的Metric聚合:Elasticsearch(8) --- 聚合查詢(Metric聚合)
說明
本文主要參考於Elasticsearch 官方文檔 7.3版本。 Bucket Aggregations
概念
:Bucket 可以理解為一個桶,它會遍歷文檔中的內容,凡是符合某一要求的就放入一個桶中,分桶相當與 SQL 中的 group by。
這篇博客講的桶的關鍵字有:Terms Aggregation
、Filter Aggregation
、Histogram Aggregation
、Range Aggregation
、Date Aggregation
。
一、創建索引、數據
1、創建索引
DELETE cars
PUT cars
{
"mappings": {
"properties": {
"price": {
"type":"long"
},
"color": {
"type":"keyword"
},
"brand": {
"type":"keyword"
},
"sellTime": {
"type":"date"
}
}
}
}
屬性字段:價格、顏色、品牌、銷售時間
2、添加索引數據
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、查看是否成功
命令
GET /_cat/count/cars?v
可以看到該索引存在,並且有8條文檔數據。
二、Terms Aggregation
官方7.3文檔:Terms Aggregation
概念
: 根據某一項的每個唯一的值的聚合。
1、根據品牌分桶
GET cars/_search?size=0
{
"aggs" : {
"genres" : {
"terms" : { "field" : "brand" }
}
}
}
返回結果
2、分桶后只顯示文檔數量前3的桶
GET cars/_search?size=0
{
"aggs" : {
"cars" : {
"terms" : {
"field" : "brand",
"size" : 3
}
}
}
}
返回
從圖中可以看出文檔數量前三的桶。
3、分桶后排序
GET cars/_search?size=0
{
"aggs" : {
"genres" : {
"terms" : {
"field" : "brand",
"order" : { "_count" : "asc" }
}
}
}
}
4、顯示文檔數量大於3的桶
GET cars/_search?size=0
{
"aggs" : {
"brands" : {
"terms" : {
"field" : "brand",
"min_doc_count": 3
}
}
}
}
5、使用精確指定的詞條進行分桶
GET /cars/_search?size=0
{
"aggs" : {
"JapaneseCars" : {
"terms" : {
"field" : "brand",
"include" : ["BMW", "Audi"]
}
}
}
}
這里也只展示些常用的,更多有關Terms Aggregation那就看官網吧。
三、 Filter Aggregation
官方文檔: Filter Aggregation 和 Filters Aggregation
Filter概念
:指具體的域和具體的值,可以說是在 Terms Aggregation 的基礎上進行了過濾,只對特定的值進行了聚合。
1、過濾獲取品牌為BMW的桶,並求該桶平均值
GET /cars/_search?size=0
{
"aggs" : {
"brands" : {
"filter" : { "term": { "brand": "BMW" } },
"aggs" : {
"avg_price" : { "avg" : { "field" : "price" } }
}
}
}
}
返回
2、過濾獲取品牌為BMW的或者color為綠色的桶
Filters概念
: Filter Aggreagtion 只能指定一個過濾條件,響應也只是單個桶。如果想要只對多個特定值進行聚合,使用 Filter Aggreagtion 只能進行多次請求。
而使用 Filters Aggreagation 就可以解決上述的問題,它可以指定多個過濾條件,也是說可以對多個特定值進行聚合。
GET /cars/_search?size=0
{
"size": 0,
"aggs" : {
"cars" : {
"filters" : {
"filters" : {
"colorBucket" : { "match" : { "color" : "red" }},
"brandBucket" : { "match" : { "brand" : "Audi" }}
}
}
}
}
}
返回
四、Histogram Aggreagtion
概念
Histogram與Terms聚合類似,都是數據分組,區別是Terms是按照Field的值分組,而Histogram可以按照指定的間隔對Field進行分組
1、根據價格區間為10000分桶
GET /cars/_search?size=0
{
"aggs" : {
"prices" : {
"histogram" : {
"field" : "price",
"interval" : 10000
}
}
}
}
返回
2、根據價格區間為10000分桶,同時如果桶中沒有文檔就不顯示桶
上面的分桶我們可以發現價格在5000~6000 的文檔沒有也顯示為0,我們想把如果桶中沒有文檔就不顯示該桶
GET /cars/_search?size=0
{
"aggs" : {
"prices" : {
"histogram" : {
"field" : "price",
"interval" : 10000,
"min_doc_count" : 1
}
}
}
}
返回
五、Range Aggregation
官方文檔:Range Aggregation
概念
: 根據用戶傳遞的范圍參數作為桶,進行相應的聚合。在同一個請求中,可以傳遞多組范圍,每組范圍作為一個桶。
1、根據價格區間分桶
GET /cars/_search?size=0
{
"aggs" : {
"price_ranges" : {
"range" : {
"field" : "price",
"ranges" : [
{ "to" : 50000 },
{ "from" : 5000, "to" : 80000 },
{ "from" : 80000 }
]
}
}
}
}
返回
我們也可以指定key的名稱
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 }
]
}
}
}
}
返回
六、 Date Aggregation
官方文檔: Date Histogram Aggregation 和 Date Range Aggregation
Date Histogram概念
針對於時間格式數據的直方圖聚合,基本的特性與 Histogram Aggregation 一致。
1、按月分桶顯示每個月的銷量
注意
官方文檔這里不是interval而是calendar_interval,但是按照這樣操作會報錯,因為我看的7.3的文檔,而我部署的es是7.1版本。說明這個地方7.3有了改進。
POST /cars/_search?size=0
{
"aggs" : {
"sales_over_time" : {
"date_histogram" : {
"field" : "sellTime",
"interval" : "1M",
"format" : "yyyy-MM-dd"
}
}
}
}
返回
2、根據指定時間區間分桶
Date Range概念
:針對於時間格式數據的范圍聚合,基本的特性與 Range Aggreagtion 一致。
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個月前之后的分為一個桶
參考
1、Elasticsearch核心技術與實戰---阮一鳴(eBay Pronto平台技術負責人
3、Elasticsearch聚合——Bucket Aggregations
我相信,無論今后的道路多么坎坷,只要抓住今天,遲早會在奮斗中嘗到人生的甘甜。抓住人生中的一分一秒,勝過虛度中的一月一年!(14)