-
什么品牌的手機最受歡迎?
-
這些手機的平均價格、最高價格、最低價格?
-
這些手機每月的銷售情況如何?
實現這些統計功能的比數據庫的sql要方便的多,而且查詢速度非常快,可以實現近實時搜索效果。
聚合的種類
聚合常見的有三類:
-
桶(Bucket)聚合:用來對文檔做分組
-
TermAggregation:按照文檔字段值分組,例如按照品牌值分組、按照國家分組
-
Date Histogram:按照日期階梯分組,例如一周為一組,或者一月為一組
-
-
度量(Metric)聚合:用以計算一些值,比如:最大值、最小值、平均值等
-
Avg:求平均值
-
Max:求最大值
-
Min:求最小值
-
Stats:同時求max、min、avg、sum等
-
-
管道(pipeline)聚合:其它聚合的結果為基礎做聚合
注意:參加聚合的字段必須是keyword、日期、數值、布爾類型
語法如下:
GET /hotel/_search { "size": 0, // 設置size為0,結果中不包含文檔,只包含聚合結果 "aggs": { // 定義聚合 "brandAgg": { //給聚合起個名字 "terms": { // 聚合的類型,按照品牌值聚合,所以選擇term "field": "brand", // 參與聚合的字段 "size": 20 // 希望獲取的聚合結果數量 } } } }
2.聚合結果排序
默認情況下,Bucket聚合會統計Bucket內的文檔數量,記為count,並且按照count降序排序。
我們可以指定order屬性,自定義聚合的排序方式:
GET /hotel/_search { "size": 0, "aggs": { "brandAgg": { "terms": { "field": "brand", "order": { "_count": "asc" // 按照_count升序排列 }, "size": 20 } } } }
3.限定聚合范圍
默認情況下,Bucket聚合是對索引庫的所有文檔做聚合,但真實場景下,用戶會輸入搜索條件,因此聚合必須是對搜索結果聚合。那么聚合必須添加限定條件。
我們可以限定要聚合的文檔范圍,只要添加query條件即可:
GET /hotel/_search { "query": { "range": { "price": { "lte": 200 // 只對200元以下的文檔聚合 } } }, "size": 0, "aggs": { "brandAgg": { "terms": { "field": "brand", "size": 20 } } } }
這次,聚合得到的品牌明顯變少了:
4.Metric聚合語法
上節課,我們對酒店按照品牌分組,形成了一個個桶。現在我們需要對桶內的酒店做運算,獲取每個品牌的用戶評分的min、max、avg等值。
這就要用到Metric聚合了,例如stat聚合:就可以獲取min、max、avg等結果。
語法如下:
GET /hotel/_search { "size": 0, "aggs": { "brandAgg": { "terms": { "field": "brand", "size": 20 }, "aggs": { // 是brands聚合的子聚合,也就是分組后對每組分別計算 "score_stats": { // 聚合名稱 "stats": { // 聚合類型,這里stats可以計算min、max、avg等 "field": "score" // 聚合字段,這里是score } } } } } }
這次的score_stats聚合是在brandAgg的聚合內部嵌套的子聚合。因為我們需要在每個桶分別計算。
另外,我們還可以給聚合結果做個排序,例如按照每個桶的酒店平均分做排序:
5.小結
aggs代表聚合,與query同級,此時query的作用是?
-
限定聚合的的文檔范圍
聚合必須的三要素:
-
聚合名稱
-
聚合類型
-
聚合字段
聚合可配置屬性有:
-
size:指定聚合結果數量
-
order:指定聚合結果排序方式
-
field:指定聚合字段