Elasticsearch(9) --- 聚合查詢(Bucket聚合)
Elasticsearch(9) --- 聚合查詢(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 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,但是按照這樣操作會報錯,不知道是什麼原因
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平臺技術負責人
2、ES7.3版官方聚合查詢API
3、Elasticsearch聚合——Bucket Aggregations
4、ElasticSearch-聚合bucket
我相信,無論今後的道路多麼坎坷,只要抓住今天,遲早會在奮鬥中嚐到人生的甘甜。抓住人生中的一分一秒,勝過虛度中的一月一年!(14)
<