HM-SpringCloud微服務系列7.1【資料聚合】
阿新 • • 發佈:2022-03-29
-
聚合(aggregations):實現對文件資料的統計、分析、運算。例如:
- 什麼品牌的手機最受歡迎?
- 這些手機的平均價格、最高價格、最低價格?
- 這些手機每月的銷售情況如何?
- 實現這些統計功能的比資料庫的sql要方便的多,而且查詢速度非常快,可以實現近實時搜尋效果。
1 聚合的種類
- 聚合常見的有三類:
-
桶(Bucket)聚合:對文件資料做分組,並統計每組數量
- TermAggregation:按照文件欄位值分組,例如按照品牌值分組、按照國家分組
- Date Histogram:按照日期階梯分組,例如一週為一組,或者一月為一組
-
度量(Metric)聚合:對文件資料進行計算,比如:最大值、最小值、平均值等
- Avg:求平均值
- Max:求最大值
- Min:求最小值
- Stats:同時求max、min、avg、sum等
- 管道(pipeline)聚合:其它聚合的結果為基礎再做聚合
-
桶(Bucket)聚合:對文件資料做分組,並統計每組數量
- 注意:參加聚合的欄位必須是keyword、日期、數值、布林型別
2 DSL實現聚合
2.1 Bucket聚合語法
-
案例需求:統計所有資料中的酒店品牌有幾種,其實就是按照品牌對資料分組。此時可以根據酒店品牌的名稱做聚合,也就是Bucket聚合,型別為term。
-
DSL語法
GET /hotel/_search { "size": 0, // 設定size為0,結果中不包含文件,只包含聚合結果 "aggs": { // 定義聚合 "brandAgg": { //給聚合起個名字 "terms": { // 聚合的型別,按照品牌值聚合,所以選擇term "field": "brand", // 參與聚合的欄位 "size": 20 // 希望獲取的聚合結果數量 } } } }
-
實操
點選檢視程式碼
# 聚合功能 GET /hotel/_search { "size": 0, "aggs": { "brangAgg": { "terms": { "field": "brand", "size": 10 } } } }
點選檢視程式碼
{ "took" : 584, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 201, "relation" : "eq" }, "max_score" : null, "hits" : [ ] }, "aggregations" : { "brangAgg" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 39, "buckets" : [ { "key" : "7天酒店", "doc_count" : 30 }, { "key" : "如家", "doc_count" : 30 }, { "key" : "皇冠假日", "doc_count" : 17 }, { "key" : "速8", "doc_count" : 15 }, { "key" : "萬怡", "doc_count" : 13 }, { "key" : "華美達", "doc_count" : 13 }, { "key" : "和頤", "doc_count" : 12 }, { "key" : "萬豪", "doc_count" : 11 }, { "key" : "喜來登", "doc_count" : 11 }, { "key" : "希爾頓", "doc_count" : 10 } ] } } }
2.2 聚合結果排序
- 預設情況下,Bucket聚合會統計Bucket內的文件數量,記為_count,並且按照_count降序排序。
- 可以指定order屬性,自定義聚合的排序方式:
GET /hotel/_search { "size": 0, "aggs": { "brandAgg": { "terms": { "field": "brand", "order": { "_count": "asc" // 按照_count升序排列 }, "size": 20 } } } }
- 實操
2.3 限定聚合範圍
-
預設情況下,Bucket聚合是對索引庫的所有文件做聚合,但真實場景下,使用者會輸入搜尋條件,因此聚合必須是對搜尋結果聚合。那麼聚合必須新增限定條件。
-
我們可以限定要聚合的文件範圍,只要新增query條件即可:
GET /hotel/_search { "query": { "range": { "price": { "lte": 200 // 只對200元以下的文件聚合 } } }, "size": 0, "aggs": { "brandAgg": { "terms": { "field": "brand", "size": 20 } } } }
-
實操
點選檢視程式碼
# 聚合功能,限定聚合範圍 GET /hotel/_search { "query": { "range": { "price": { "lte": 200 } } }, "size": 0, "aggs": { "brangAgg": { "terms": { "field": "brand", "size": 10 } } } }
點選檢視程式碼
{ "took" : 92, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 17, "relation" : "eq" }, "max_score" : null, "hits" : [ ] }, "aggregations" : { "brangAgg" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "如家", "doc_count" : 13 }, { "key" : "速8", "doc_count" : 2 }, { "key" : "7天酒店", "doc_count" : 1 }, { "key" : "漢庭", "doc_count" : 1 } ] } } }
-
小結
2.4 Metric聚合語法
- 此前我們對酒店按照品牌分組,形成了一個個桶。
- 現在我們需要對桶內的酒店做運算,獲取每個品牌的使用者評分的min、max、avg等值。
- 這就要用到Metric聚合了,例如stat聚合:就可以獲取min、max、avg等結果。
- DSL語法如下:
GET /hotel/_search { "size": 0, "aggs": { "brandAgg": { "terms": { "field": "brand", "size": 20 }, "aggs": { // 是brands聚合的子聚合,也就是分組後對每組分別計算 "score_stats": { // 聚合名稱 "stats": { // 聚合型別,這裡stats可以計算min、max、avg等 "field": "score" // 聚合欄位,這裡是score } } } } } }