一、聚合分析的簡單介紹
- 聚合分析,英文爲 Aggregation,是es 除搜索功能外提供的針對es數據做統計分析的功能。
- es聚合分析功能豐富,提供 Bucket、Metric、Pipeline等多種分析方式,可以滿足大部分的分析需求;
- 實時性高,所有的計算結果是即時返回的,而Hadoop 等大數據系統一般都是 T+1 級別的。
- 語法如下:
GET testindex/_search
{
"size": 0,
"aggs": { // 關鍵詞,與query 同級
"agg_name": { // 自定義的聚合名稱
"agg_type": { // 聚合分析的定義,包含type 和 body 定義
"agg_body"
},
[,"aggs": {"sub_agg"}] // 子聚合
},
"agg_name2": {....} // 可以包含多個聚合
}
}
二、聚合分析之分類
- Bucket,分桶類型,類似 SQL 中的 group by 語法;
- Metric,指標分析類型,如計算最大值、最小值、平均值等;
- Pipeline,管道分析類型,基於上一級的聚合分析結果進行再分析;
- Matrix,矩陣分析類型。
三、Bucket 聚合分析
Bucket,意味 ’桶‘,即按照一定的規則將文檔分配到不同的桶中,達到分類的目的。
按照Bucket 的分桶策略,常見的Bucket 聚合分析如下:
-
Terms:直接按照term來分桶。如果是text 類型(需要開啓fielddata),則按照分詞後的結果分桶。
-
Range:通過制定數值的範圍內設定分桶規則
// *-10000,10000-20000,20000-* 三個區間的文檔數聚合 GET testinde/_search { "aggs": { "salary_range": { "range": { "field": "salary", "ranges": [ { "key": "<10000", // 自定義key 值的名字 "to": 10000 }, { "from": 10000, "to": 20000, }, { "from": 20000 } ] } } } }
-
Date Range:通過制定日期的範圍來設定分桶規則
GET testindex/_search
{
"aggs": {
"date_range": {
"range": {
"field": "birth",
"format": "yyyy-MM-dd", // 指定返回結果的日期格式
"ranges": [
{
"from": "2019-09-01", // 指定日期範圍,可以使用date match
"to": "2019-09-30"
}
]
}
}
}
}
- Histogram:直方圖,以固定間隔的策略來分割數據
GET testindex/_search
{
"aggs": {
"salary_hist": {
"histogram": { // 關鍵詞
"field": "salary",
"interval": 5000, // 指定間隔大小
"extended_bounds": { // 指定數據範圍
"min": 0,
"max": 50000
}
}
}
}
}
- Date Histogram:針對日期的直方圖或者柱狀圖,是時序數據分析中的常用聚合分析類型
GET testindex/_search
{
"aggs": {
"by_year": {
"date_histogram": { // 關鍵詞
"field": "birth",
"interval": "year", // 指定間隔大小
"format": "yyyy"
}
}
}
}
四、Metric 聚合分析
主要分如下2類:
- 單值分析,只輸出一個分析結果,常見的有min ,max ,avg ,sum , cardinality
- 多值分析,輸出多個分析結果,常見的有stats ,extended stats ,percentile , percentile rank ,top hits
1、cardinality
集合的勢,或者基數,是指不同數值的個數。可以類比成 SQL 中的 distinct count意思。分組求和,比如某列的數值有多個不同的值。
2、stats
返回一系列數值類型的統計值,包含了min、max、avg、sum和count。一次做了多種分析。
3、extended_stats
顧名思義,是對stats的擴展,包含了更多的統計數據,如方差、標準差等。
4、percentiles與percentile_ranks
百分位數統計。如下:
// 比如:第一行的意思是18歲以下的人數佔1.0%
{
"took": 55,
......
"aggregations": {
"per_age": {
"1.0": 18,
"5.0": 25,
"25.0": 29,
"50.0": 31,
"75.0": 40,
"95.0": 60,
"99.0": 80
}
}
}
// 指定展示的百分位數(只展示95%,99%,99.9%的數據)
GET testindex/_search
{
"aggs": {
"per_salary": {
"percentiles": {
"field": "salary",
"percents": [
95,
99,
99.9
]
}
}
}
}
5、top_hits
一般用於分桶聚合後,獲取該桶內最匹配的頂部文檔列表,即詳情數據。如下:
GET testindex/_search
{
"aggs": {
"group_jobs": {
"terms": { // 分桶聚合
"field": "job.keyword"
},
"aggs": {
"top_employee": {
"top_hits": { // 關鍵詞
"size": 10,
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
}
}
}
}
}
五、Bucket + Metric 聚合分析
Bucket 聚合分析允許通過添加子分析來進一步分析,該子分析可以是 Bucket 也可以是 Metric。
六、pipeline 聚合分析
pipeline的分析結果會輸出到原結果中,根據輸出位置的不同,可以分爲2類。
1、parent 結果內嵌到現有的聚合分析結果中:
- Derivative:計算Bucket 值的導數。
- Moving Average:計算Bucket值的移動平均值。
- Cumulative Sum:計算Bucket值的累計加和。
2、Sibling 結果與現有聚合分析結果同級
- Max/Min/Avg/Sum Bucket
- Stats/Extended Stats Bucket
- Percentiles Bucket
七、聚合分析作用範圍
es聚合分析默認作用範圍是 query 的結果集,可以通過 filter、post_filter、global 改變其作用範圍。
filter
它是爲某個聚合分析設定過濾條件的,從而在不更改整體query 語句的情況下修改作用範圍。
post_filter
作用於文檔過濾,但在聚合分析後生效,過濾輸出的結果。
global
無視query的過濾條件,基於全部文檔進行分析。比如你在query裏面進行了文檔過濾,但是global還是會基於全部文檔去分析。
八、排序
可以使用自帶的關鍵數據進行排序,比如:
- _count 文檔數
- _key 按照key值排序
GET testindex/_search
{
"aggs": {
"group_jobs": {
"terms": { // 分桶聚合
"field": "job.keyword",
"order": { // 排序
"_count": "asc"
}
}
}
}
}
九、聚合分析精度問題
max、min這種是精確地,但是 terms 是不一定精確地。可以通過參數來優化它。
- 設置shard 數爲1,消除數據分散的問題,但缺點比較明顯,無法承載大數據量。
- 合理設置 shard_size 大小,即每次從shard 上額外多獲取數據,以提升精確度。
terms 聚合返回結果中有如下2個統計值:
- doc_count_error_upper_bound 被遺漏的 term 可能的最大值
- sum_other_doc_count 返回結果 bucket 的term外,其他term的文檔總數
注:shard_size大小的設定方法
設定show_term_doc_count_error=true可以查看每個bucket誤算的最大值。當其返回結果的doc_count_error_upper_bound=0,則說明計算是準確的,不存在誤差。
GET testindex/_search
{
"aggs": {
"jobs": {
"terms": {
"field": "job.keyword",
"show_term_doc_count_error": true
}
}
}
}
shard_size默認大小如下:shard_size=size * 1.5 + 10
通過調整shard_size 的大小降低doc_count_error_upper_bound來提升準確度(隨之而來的影響是增大了整體的計算量,從而降低了響應時間)
GET testindex/_search
{
"aggs": {
"jobs": {
"terms": {
"field": "job.keyword",
"shard_size": 10, // 關鍵詞
"show_term_doc_count_error": true
}
}
}
}