大家好,我是Edison。
上一篇:ES的Query DSL
什麼是ES的聚合
Elastic除搜索之外,還提供針對ES數據的統計分析功能,具有較高的實時性。
通過聚合,我們可以得到一個數據的概覽,它是分析和總結全套的數據,而不是尋找單個文檔。
例如,我們可以通過聚合得到一個旅遊網站的以下數據:
-
地區A 和 地區B 的客房數量
-
不同的價格區間,可以預定的經濟性酒店和舒適型酒店的數量
使用ES聚合,我們只需要一條語句,就可以從ES得到分析的結果,無需在客戶端去實現。在Kibana中,大量的可視化報表其實都是採用了ES的聚合分析來得到的數據結果。
ES聚合的分類
ES中常見的聚合有如下幾類:
-
Bucket Aggregation - 一些列滿足特定條件的文檔集合
-
Metric Aggregation - 一些數學運算,可以對文檔字段進行統計分析
-
Pipeline Aggregation - 對其他的聚合結果進行二次聚合
-
Matrix Aggregation - 支持對多個字段的操作並提供一個結果矩陣
那麼,接下來,我們就一起來看看最常用的Bucket & Metric聚合。
Bucket & Metric
這裏我們直接用我們都很熟悉的SQL語句來理解Bucket和Metric:
Metric就類似於SQL中的一些聚合函數方法,主要對數據集進行計算。
大多數Metric是數學計算,僅僅輸出一個值,如:min / max / sum / avg / cardinality
少部分Metric支持輸出多個數值,如:stats / percentiles / percentile_ranks
Bucket就類似於SQL中對數據進行分組,主要指滿足一定條件的文檔集合。
我們可以藉助Bucket實現數據的分桶,例如可以實現酒店的高檔、中檔和低檔的分桶,也可以在高檔的分組下再分爲好評、中評和差評三個分桶。
ES中提供了多種類型的Bucket,例如 Term & Range,可以讓我們輕鬆地實現時間 / 年齡區間 / 地理位置的分桶。
下面我們來看一個Bucket的例子:
查看航班目的地的統計信息
分桶字段:DestCountry (目的地)
// 按照字段的Terms進行分桶 GET kibana_sample_data_flights/_search { "size": 0, "aggs": { "flight_dest": { "terms": { "field": "DestCountry" } } } }
統計結果如下圖所示:
可以從結果圖中看出,ES返回了以航班目的地爲分組的的Buckets(分桶),IT(意大利)的航班有2371次,US(美麗國)的航班有1987次...
下面我們來看一個加入Metirc的例子:
查看航班目的地的統計信息,並增加均價、最高價 和 最低價的統計
這裏我們就可以使用ES提供的數學計算Metrics了
GET kibana_sample_data_flights/_search { "size": 0, "aggs": { "flight_dest": { "terms": { "field": "DestCountry" }, "aggs": { // 自定義名字爲 avaerage_price "average_price": { // 使用 avg metric "avg": { "field": "AvgTicketPrice" } }, // 自定義名字爲 max_price "max_price": { // 使用 max metric "max": { "field": "AvgTicketPrice" } }, // 自定義名字爲 min_price "min_price": { // 使用 min metric "min": { "field": "AvgTicketPrice" } } } } } }
統計結果如下圖所示:
可以從結果圖中看出,ES在之前分組統計的基礎上,還把平均價格、最高價和最低價都統計出來了。
相信到這裏,你已經初步瞭解基本的統計分析了。
聚合嵌套
如果想要在上面的聚合統計基礎之上,再做進一步的詳細分析,我們就可以使用聚合嵌套。
還是以上面的示例爲基礎,我們想要:
查看航班目的地的統計信息,平均票價,以及天氣情況。
天氣情況是基於之前對航班目的地的聚合統計的基礎之上,做的二次聚合,類似於在第一個Bucket中再分幾個Bucket,這個就是聚合嵌套。
GET kibana_sample_data_flights/_search { "size": 0, "aggs": { "flight_dest": { "terms": { "field": "DestCountry" }, "aggs": { "average_price": { "avg": { "field": "AvgTicketPrice" } }, // 聚合嵌套 "weather": { "terms": { "field": "DestWeather" } } } } } }
統計結果如下圖所示:
可以看到,ES在以航班目的地爲分組的Bucket下,又爲我們分出了多個Bucket,這些嵌套的Bucket就是我們想要統計的天氣情況。比如,圖中航班目的地爲CN(中國)的天氣情況中,Sunny(晴朗)天氣的記錄有209條,而Rain(下雨)天氣的記錄有207條。
小結
本篇,我們瞭解了ElasticSearch的聚合的概念,以及兩個重要的聚合 Bucket & Metric。通過一個查詢實例,我們瞭解瞭如何使用 Bucket & Metric 進行最基本的統計分析,ES的聚合還支持嵌套,還是很強大的!
參考資料
極客時間,阮一鳴,《ElasticSearch核心技術與實戰》