大家好,我是咔咔 不期速成,日拱一卒
ElasticSearch致力于搜索的同時柠傍,也提供了聚合實(shí)時分析數(shù)據(jù)的功能馋嗜,聚合可以實(shí)現(xiàn)把復(fù)雜的數(shù)據(jù)進(jìn)行一系列計(jì)算后得出我們想要的數(shù)據(jù)齐板。
雖然聚合的功能與搜索完全不同,但使用的數(shù)據(jù)結(jié)構(gòu)是完全相同的葛菇,因此聚合的執(zhí)行速度很快甘磨,也就是說在一次請求中對相同數(shù)據(jù)可以同時進(jìn)行搜索+過濾、分析眯停。
在ElasticSearch中聚合共分為四大類:
- Bucket Aggregation:分桶類型济舆,一些列滿足特定條件的文檔集合
- Metric Aggregation:指標(biāo)分析類型,對數(shù)據(jù)進(jìn)行數(shù)學(xué)運(yùn)算莺债,例如求最大滋觉、小值
- Pipeline Aggregation:管道分析類型,已經(jīng)聚合的結(jié)果進(jìn)行二次聚合
- Matix Aggregation:矩陣分析類型齐邦,支持對多個字段操作并提供一個結(jié)果矩陣
先從簡開始椎侠,看一下Bucket、Metric這兩種類型侄旬,Bucket實(shí)現(xiàn)的結(jié)果就是MySQL中g(shù)roup關(guān)鍵字的使用肺蔚,Metric則是MySQL中max、min函數(shù)的使用儡羔。
一宣羊、Buckert Aggregation
介紹
通過上圖可得知將數(shù)據(jù)分為了三個桶,第一個桶統(tǒng)計(jì)的是身高小于300汰蜘,第二個桶統(tǒng)計(jì)的是身高大于600仇冯,第三個桶統(tǒng)計(jì)的是身高在300到600之間的,在這個案例中就是根據(jù)不同的身高分到不同的桶中族操。
使用聚合分析機(jī)制還可以按照年齡苛坚、地理位置、性別色难、薪資范圍泼舱、訂單增長情況、工作崗位分布等枷莉。只要有一定共同點(diǎn)的數(shù)據(jù)都可使用聚合進(jìn)行歸檔處理涤久。
常見的Bucket分桶策略
- terms:按照term來分桶卷谈,如果是text類型則會按照分詞后的結(jié)果進(jìn)行分桶
- range:指定數(shù)值的范圍來設(shè)定分桶規(guī)則
- data range:指定日期的范圍來設(shè)定分桶規(guī)則
- histogram:固定的間隔來來設(shè)定分桶規(guī)則
- data histogram:針對日期的直方圖或柱狀圖
Terms
根據(jù)目的地進(jìn)行分桶
post /kibana_sample_data_flights/_search
{
"size":0,
"aggs":{
"destcountry_term":{
"terms": {
"field": "DestCountry"
}
}
},
"profile":"true"
}
從返回結(jié)果中看到根據(jù)目的地將航班信息進(jìn)行了歸類處理掠拳,同時也會發(fā)現(xiàn)在ElasticSearch中如果不手動定義size值都會默認(rèn)只返回10條結(jié)果
"aggregations" : {
"destcountry_term" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 3187,
"buckets" : [
{
"key" : "IT",
"doc_count" : 2371
},
{
"key" : "US",
"doc_count" : 1987
},
{
"key" : "CN",
"doc_count" : 1096
},
{
"key" : "CA",
"doc_count" : 944
},
{
"key" : "JP",
"doc_count" : 774
},
{
"key" : "RU",
"doc_count" : 739
},
{
"key" : "CH",
"doc_count" : 691
},
{
"key" : "GB",
"doc_count" : 449
},
{
"key" : "AU",
"doc_count" : 416
},
{
"key" : "PL",
"doc_count" : 405
}
]
}
}
Range
想要查詢平均價格在300以下、300~600之間噪裕、大于600的案例
post /kibana_sample_data_flights/_search
{
"size":0,
"aggs":{
"avgticketprice_range":{
"range": {
"field": "AvgTicketPrice",
"ranges": [
{"to":300},
{"from":300,"to":600},
{"from":600}
]
}
}
}
}
返回結(jié)果如下,可以三條結(jié)果都根據(jù)不同的區(qū)間設(shè)置了key值
"aggregations" : {
"avgticketprice_range" : {
"buckets" : [
{
"key" : "*-300.0",
"to" : 300.0,
"doc_count" : 1816
},
{
"key" : "300.0-600.0",
"from" : 300.0,
"to" : 600.0,
"doc_count" : 4115
},
{
"key" : "600.0-*",
"from" : 600.0,
"doc_count" : 7128
}
]
}
}
可以通過設(shè)置keyed:true股毫,使每個區(qū)間都返回一個特定的名字
post /kibana_sample_data_flights/_search
{
"size":0,
"aggs":{
"avgticketprice_range":{
"range": {
"field": "AvgTicketPrice",
"keyed":"true",
"ranges": [
{"to":300},
{"from":300,"to":600},
{"from":600}
]
}
}
}
}
可以好好的跟上一個案例對比一下區(qū)別
"aggregations" : {
"avgticketprice_range" : {
"buckets" : {
"*-300.0" : {
"to" : 300.0,
"doc_count" : 1816
},
"300.0-600.0" : {
"from" : 300.0,
"to" : 600.0,
"doc_count" : 4115
},
"600.0-*" : {
"from" : 600.0,
"doc_count" : 7128
}
}
}
}
當(dāng)然也可以指定區(qū)間的名字
post /kibana_sample_data_flights/_search
{
"size":0,
"aggs":{
"avgticketprice_range":{
"range": {
"field": "AvgTicketPrice",
"keyed":"true",
"ranges": [
{"key":"小于300","to":300},
{"key":"300到600之間","from":300,"to":600},
{"key":"大于600","from":600}
]
}
}
}
}
返回結(jié)果
"aggregations" : {
"avgticketprice_range" : {
"buckets" : {
"小于300" : {
"to" : 300.0,
"doc_count" : 1816
},
"300到600之間" : {
"from" : 300.0,
"to" : 600.0,
"doc_count" : 4115
},
"大于600" : {
"from" : 600.0,
"doc_count" : 7128
}
}
}
}
Data Range
通過指定日期的范圍來設(shè)定分桶規(guī)則膳音,如對timestamp字段按照設(shè)定的時間段來分桶。
post /kibana_sample_data_flights/_search
{
"size":0,
"aggs":{
"data_range_timestamp":{
"date_range":{
"field":"timestamp",
"format":"yyyy-MM",
"ranges":[
{"from":"2022-01","to":"2022-02"},
{"from":"2022-02","to":"2022-03"}
]
}
}
}
}
返回結(jié)果铃诬,思考一下如果想要設(shè)置固定的key值應(yīng)該怎么設(shè)置呢祭陷?還有要注意的是日期格式yyyy-MM-dd HH:mm:ss
"aggregations" : {
"data_range_timestamp" : {
"buckets" : [
{
"key" : "2022-01-2022-02",
"from" : 1.6409952E12,
"from_as_string" : "2022-01",
"to" : 1.6436736E12,
"to_as_string" : "2022-02",
"doc_count" : 9580
},
{
"key" : "2022-02-2022-03",
"from" : 1.6436736E12,
"from_as_string" : "2022-02",
"to" : 1.6460928E12,
"to_as_string" : "2022-03",
"doc_count" : 1837
}
]
}
}
Historgram
直方圖,以固定間隔的策略來分割數(shù)據(jù)氧急,如對AvgTicketPrice字段按照100的間隔進(jìn)行分桶
- interval :每次間隔50
- min_doc_count :存在的文檔數(shù)最少是0條
- extended_bounds :此值只有當(dāng)min_doc_count 為0時才具有意義
在實(shí)現(xiàn)時你會發(fā)現(xiàn)extended_bounds不過濾桶颗胡。extended_bounds.min高于從文檔中提取的值毫深,那么文檔仍然會規(guī)定第一個存儲段將是什么(對于extended_bounds.max和最后一個存儲段也是如此)吩坝。為了過濾桶,您應(yīng)該將直方圖聚合嵌套在范圍過濾器聚合中哑蔫,并使用適當(dāng)?shù)膹?到設(shè)置
post /kibana_sample_data_flights/_search
{
"size":0,
"aggs":{
"price_histogram":{
"histogram": {
"field": "AvgTicketPrice",
"interval": 50,
"min_doc_count":"0",
"extended_bounds":{
"min":0,
"max":600
}
}
}
}
}
返回結(jié)果
"aggregations" : {
"price_histogram" : {
"buckets" : [
{
"key" : 0.0,
"doc_count" : 0
},
{
"key" : 50.0,
"doc_count" : 0
},
{
"key" : 100.0,
"doc_count" : 380
},
{
"key" : 150.0,
"doc_count" : 369
},
{
"key" : 200.0,
"doc_count" : 398
}
]
}
}
Data histogram
針對日期的直方圖或者柱狀圖钉寝,是時序數(shù)據(jù)分析中常用的聚合分析類型,如對timestamp字段按照月的間隔進(jìn)行分桶
post /kibana_sample_data_flights/_search
{
"size":0,
"aggs":{
"timestamp_data_histogram":{
"date_histogram": {
"field": "timestamp",
"interval": "month",
"min_doc_count": 0,
"format": "yyyy-MM-dd",
"extended_bounds": {
"min": "2021-10-10",
"max": "2022-01-19"
}
}
}
}
}
返回結(jié)果
"aggregations" : {
"timestamp_data_histogram" : {
"buckets" : [
{
"key_as_string" : "2021-10-01",
"key" : 1633046400000,
"doc_count" : 0
},
{
"key_as_string" : "2021-11-01",
"key" : 1635724800000,
"doc_count" : 0
},
{
"key_as_string" : "2021-12-01",
"key" : 1638316800000,
"doc_count" : 1642
},
{
"key_as_string" : "2022-01-01",
"key" : 1640995200000,
"doc_count" : 9580
},
{
"key_as_string" : "2022-02-01",
"key" : 1643673600000,
"doc_count" : 1837
}
]
}
}
二闸迷、嵌套查詢
上文中列舉了五種分桶的實(shí)現(xiàn)嵌纲,在實(shí)際開發(fā)中只是單一的進(jìn)行聚合查詢是非常少的,大多情況下都是會進(jìn)行嵌套操作腥沽。
先根據(jù)機(jī)票進(jìn)行分桶后逮走,再對分桶后的數(shù)據(jù)取總數(shù)、最小值今阳、最大值师溅、平均值、總和
post /kibana_sample_data_flights/_search
{
"size":0,
"aggs":{
"price_range":{
"range": {
"field": "AvgTicketPrice",
"ranges": [
{"to":300},
{"from":300,"to":600},
{"from":600}
]
},
"aggs":{
"price_status":{
"stats": {
"field": "AvgTicketPrice"
}
}
}
}
}
}
返回結(jié)果(返回結(jié)果截取顯示了)
"aggregations" : {
"price_range" : {
"buckets" : [
{
"key" : "*-300.0",
"to" : 300.0,
"doc_count" : 1816,
"price_status" : {
"count" : 1816,
"min" : 100.0205307006836,
"max" : 299.9529113769531,
"avg" : 212.5348257619379,
"sum" : 385963.2435836792
}
}
]
}
}
還有更多的操作等待我們?nèi)ネ诰蚨苌啵劝鸦A(chǔ)的搞定墓臭,不期速成,日拱一卒
堅(jiān)持學(xué)習(xí)妖谴、堅(jiān)持寫作窿锉、堅(jiān)持分享是咔咔從業(yè)以來所秉持的信念。愿文章在偌大的互聯(lián)網(wǎng)上能給你帶來一點(diǎn)幫助膝舅,我是咔咔嗡载,下期見。
文章來自公號:咔咔閑談
獲取更多ElasticSearch學(xué)習(xí)資料