ELK第六篇:Aggregations (聚合)REST API的使用
簡介
上一篇部落格介紹了ES中的簡單查詢API的使用,本篇將介紹ES提供的聚合API的使用。ES提供的聚合功能可以用來進行簡單的資料分析。本文仍然以上一篇提供的資料為例來講解。資料如下:
studentNo | name | male | age | birthday | classNo | address | isLeader |
---|---|---|---|---|---|---|---|
1 | 劉備 | 男 | 24 | 1985-02-03 | 1 | 湖南省長沙市 | true |
2 | 關羽 | 男 | 22 | 1987-08-23 | 2 | 四川省成都市 | false |
3 | 糜夫人 | 女 | 19 | 1990-06-12 | 1 | 上海市 | false |
4 | 張飛 | 男 | 20 | 1989-07-30 | 3 | 北京市 | false |
5 | 諸葛亮 | 男 | 18 | 1992-04-27 | 2 | 江蘇省南京市 | true |
6 | 孫尚香 | 女 | 16 | 1994-05-21 | 3 | false | |
7 | 馬超 | 男 | 19 | 1991-10-20 | 1 | 黑龍江省哈爾濱市 | false |
8 | 趙雲 | 男 | 23 | 1986-10-26 | 2 | 浙江省杭州市 | false |
本文的主要內容有:
- metric API的使用
- bucketing API的使用
- 兩類API的巢狀使用
1. 聚合API
ES中的Aggregations API是從Facets功能基礎上發展而來,官網正在進行替換計劃,建議使用者使用Aggregations API,而不是Facets API。ES中的聚合上可以分為下面兩類:
- metric(度量)聚合:度量型別聚合主要針對的number型別的資料,需要ES做比較多的計算工作
- bucketing(桶)聚合:劃分不同的“桶”,將資料分配到不同的“桶”裡。非常類似sql中的group語句的含義。
metric既可以作用在整個資料集上,也可以作為bucketing的子聚合作用在每一個“桶”中的資料集上。當然,我們可以把整個資料集合看做一個大“桶”,所有的資料都分配到這個大“桶”中。
ES中的聚合API的呼叫格式如下:
"aggregations" : { // 表示聚合操作,可以使用aggs替代
"<aggregation_name>" : { // 聚合名,可以是任意的字串。用做響應的key,便於快速取得正確的響應資料。
"<aggregation_type>" : { // 聚合類別,就是各種型別的聚合,如min等
<aggregation_body> // 聚合體,不同的聚合有不同的body
}
[,"aggregations" : { [<sub_aggregation>]+ } ]? // 巢狀的子聚合,可以有0或多個
}
[,"<aggregation_name_2>" : { ... } ]* // 另外的聚合,可以有0或多個
}
1.1 度量型別(metric)聚合
(1)Min Aggregation
最小值查詢,作用於number型別欄位上。查詢2班最小的年齡值。
curl -XPOST "192.168.1.101:9200/student/student/_search" -d
'
{
"query": { // 可以先使用query查詢得到需要的資料集
"term": {
"classNo": "2"
}
},
"aggs": {
"min_age": {
"min": {
"field": "age"
}
}
}
}
'
查詢結果為:
{
"took": 19, // 前面部分資料與普通的查詢資料相同
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 1.4054651,
"hits": [
{
"_index": "student",
"_type": "student",
"_id": "2",
"_score": 1.4054651,
"_source": {
"studentNo": "2",
"name": "關羽",
"male": "男",
"age": "22",
"birthday": "1987-08-23",
"classNo": "2",
"isLeader": "false"
}
},
{
"_index": "student",
"_type": "student",
"_id": "8",
"_score": 1,
"_source": {
"studentNo": "8",
"name": "趙雲",
"male": "男",
"age": "23",
"birthday": "1986-10-26",
"classNo": "2",
"isLeader": "false"
}
},
{
"_index": "student",
"_type": "student",
"_id": "5",
"_score": 0.30685282,
"_source": {
"studentNo": "5",
"name": "諸葛亮",
"male": "男",
"age": "18",
"birthday": "1992-04-27",
"classNo": "2",
"isLeader": "true"
}
}
]
},
"aggregations": { // 聚合結果
"min_age": { // 前面輸入的聚合名
"value": 18, // 聚合後的資料
"value_as_string": "18.0"
}
}
}
上面的聚合查詢有兩個要注意的點:
可以通過query先過濾資料
返回的結果會包含聚合操作所作用的資料全集
有時候我們對作用的資料全集並不太敢興趣,我們僅僅需要最終的聚合結果。可以通過查詢型別(search_type)引數來實現這個需求。下面查詢出來的資料量會大大減少,ES內部也會在查詢時減少一些耗時的步驟,所以查詢效率會提高。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d // 注意這裡的search_type=count
'
{
"query": { // 可以先使用query查詢得到需要的資料集
"term": {
"classNo": "2"
}
},
"aggs": {
"min_age": {
"min": {
"field": "age"
}
}
}
}
'
本次的查詢結果為:
{
...
"aggregations": { // 聚合結果
"min_age": { // 前面輸入的聚合名
"value": 18, // 聚合後的資料
"value_as_string": "18.0"
}
}
}
(2)Max Aggregation
最大值查詢。下面查詢2班最大的年齡值,查詢結果為23。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
'
{
"query": {
"term": {
"classNo": "2"
}
},
"aggs": {
"max_age": {
"max": {
"field": "age"
}
}
}
}
'
(3)Sum Aggregation
數值求和。下面統計查詢2班的年齡總和,查詢結果為63。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
'
{
"query": {
"term": {
"classNo": "2"
}
},
"aggs": {
"sum_age": {
"sum": {
"field": "age"
}
}
}
}
'
(4)Avg Aggregation
計算平均值。下面計算查詢2班的年齡平均值,結果為21。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
'
{
"query": {
"term": {
"classNo": "2"
}
},
"aggs": {
"avg_age": {
"avg": {
"field": "age"
}
}
}
}
'
(5)Stats Aggregation
統計查詢,一次性統計出某個欄位上的常用統計值。下面對整個學校的學生進行簡單地統計。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
'
{
"aggs": {
"stats_age": {
"stats": {
"field": "age"
}
}
}
}
'
查詢結果為:
{
... // 次要資料省略
"aggregations": {
"stats_age": {
"count": 8, // 含有年齡資料的學生計數
"min": 16, // 年齡最小值
"max": 24, // 年齡最大值
"avg": 20.125, // 年齡平均值
"sum": 161, // 年齡總和
"min_as_string": "16.0",
"max_as_string": "24.0",
"avg_as_string": "20.125",
"sum_as_string": "161.0"
}
}
}
(6)Top hits Aggregation
取符合條件的前n條資料記錄。下面查詢全校年齡排在前2位的學生,僅需返回學生姓名和年齡。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
{
"aggs": {
"top_age": {
"top_hits": {
"sort": [ // 排序
{
"age": { // 按年齡降序
"order": "desc"
}
}
],
"_source": {
"include": [ // 指定返回欄位
"name",
"age"
]
},
"size": 2 // 取前2條資料
}
}
}
}
返回結果為:
{
...
"aggregations": {
"top_age": {
"hits": {
"total": 9,
"max_score": null,
"hits": [
{
"_index": "student",
"_type": "student",
"_id": "1",
"_score": null,
"_source": {
"name": "劉備",
"age": "24"
},
"sort": [
24
]
},
{
"_index": "student",
"_type": "student",
"_id": "8",
"_score": null,
"_source": {
"name": "趙雲",
"age": "23"
},
"sort": [
23
]
}
]
}
}
}
}
1.2 桶型別(bucketing)聚合
(1)Terms Aggregation
按照指定的1或多個欄位將資料劃分成若干個小的區間,計算落在每一個區間上記錄數量,並按指定順序進行排序。下面統計每個班的學生數,並按學生數從大到小排序,取學生數靠前的2個班級。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
'
{
"aggs": {
"terms_classNo": {
"terms": {
"field": "classNo", // 按照班號進行分組
"order": { // 按學生數從大到小排序
"_count": "desc"
},
"size": 2 // 取前兩名
}
}
}
}
'
值得注意的,取得的前2名的學生數實際上是一個近似值,ES的實現方式參見這裡。如果想要取得精確值,可以不指定size值,使其進行一次全排序,然後在程式中自行去取前2條記錄。當然,這樣做會使得ES做大量的排序運算工作,效率比較差。
(2)Range Aggregation
自定義區間範圍的聚合,我們可以自己手動地劃分區間,ES會根據劃分出來的區間將資料分配不同的區間上去。下面將全校學生按照年齡劃分為5個區間段:16歲以下、16~18、19~21、22~24、24歲以上,要求統計每一個年齡段內的學生數。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
'
{
"aggs": {
"range_age": {
"range": {
"field": "age",
"ranges": [
{
"to": 15
},
{
"from": "16",
"to": "18"
},
{
"from": "19",
"to": "21"
},
{
"from": "22",
"to": "24"
},
{
"from": "25"
}
]
}
}
}
}
'
(3)Date Range Aggregation
時間區間聚合專門針對date型別的欄位,它與Range Aggregation的主要區別是其可以使用時間運算表示式。主要包括+(加法)運算、-(減法)運算和/(四捨五入)運算,每種運算都可以作用在不同的時間域上面,下面是一些時間運算表示式示例。
now+10y:表示從現在開始的第10年。
now+10M:表示從現在開始的第10個月。
1990-01-10||+20y:表示從1990-01-01開始後的第20年,即2010-01-01。
now/y:表示在年位上做舍入運算。今天是2015-09-06,則這個表示式計算結果為:2015-01-01。說好的rounding運算呢?結果是做的flooring運算,不知道為啥,估計是我理解錯了-_-!!
下面查詢25年前及更早出生的學生數。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
'
{
"aggs": {
"range_age": {
"date_range": {
"field": "birthday",
"ranges": [
{
"to": "now-25y"
}
]
}
}
}
}
'
(4)Histogram Aggregation
直方圖聚合,它將某個number型別欄位等分成n份,統計落在每一個區間內的記錄數。它與前面介紹的Range聚合非常像,只不過Range可以任意劃分區間,而Histogram做等間距劃分。既然是等間距劃分,那麼引數裡面必然有距離引數,就是interval引數。下面按學生年齡統計各個年齡段內的學生數量,分隔距離為2歲。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
'
{
"aggs": {
"histogram_age": {
"histogram": {
"field": "age",
"interval": 2, // 距離為2
"min_doc_count": 1 // 只返回記錄數量大於等於1的區間
}
}
}
}
'
(5)Date Histogram Aggregation
時間直方圖聚合,專門對時間型別的欄位做直方圖聚合。這種需求是比較常用見得的,我們在統計時,通常就會按照固定的時間斷(1個月或1年等)來做統計。下面統計學校中同一年出生的學生數。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
'
{
"aggs": {
"data_histogram_birthday": {
"date_histogram": {
"field": "birthday",
"interval": "year", // 按年統計
"format": "yyyy" // 返回結果的key的格式
}
}
}
}
'
返回結果如下,可以看到由於上面的”format”: “yyyy”,所以返回的key_as_string只返回年的資訊。
{
"buckets": [
{
"key_as_string": "1985",
"key": 473385600000,
"doc_count": 1
},
{
"key_as_string": "1986",
"key": 504921600000,
"doc_count": 1
},
{
"key_as_string": "1987",
"key": 536457600000,
"doc_count": 1
},
{
"key_as_string": "1989",
"key": 599616000000,
"doc_count": 1
},
{
"key_as_string": "1990",
"key": 631152000000,
"doc_count": 1
},
{
"key_as_string": "1991",
"key": 662688000000,
"doc_count": 1
},
{
"key_as_string": "1992",
"key": 694224000000,
"doc_count": 1
},
{
"key_as_string": "1994",
"key": 757382400000,
"doc_count": 1
}
]
}
(6)Missing Aggregation
值缺損聚合,它是一類單桶聚合,也就是最終只會產生一個“桶”。下面統計學生資訊中位址列缺損的記錄數量。由於只有學號為6的孫尚香的地址缺損,所以統計值為1。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
'
{
"aggs": {
"missing_address": {
"missing": {
"field": "address"
}
}
}
}
'
1.3 巢狀使用
前面已經說過,聚合操作是可以巢狀使用的。通過巢狀,可以使得metric型別的聚合操作作用在每一“桶”上。我們可以使用ES的巢狀聚合操作來完成稍微複雜一點的統計功能。下面統計每一個班裡最大的年齡值。
curl -XPOST "192.168.1.101:9200/student/student/_search?search_type=count" -d
'
{
"aggs": {
"missing_address": {
"terms": {
"field": "classNo"
},
"aggs": { // 在這裡巢狀新的子聚合
"max_age": {
"max": { // 使用max聚合
"field": "age"
}
}
}
}
}
}
'
返回結果如下:
{
"buckets": [
{
"key": "1", // key是班級號
"doc_count": 3, // 每個班級內的人數
"max_age": { // 這裡是我們指定的子聚合名
"value": 24, // 每班的年齡值
"value_as_string": "24.0"
}
},
{
"key": "2",
"doc_count": 3,
"max_age": {
"value": 23,
"value_as_string": "23.0"
}
},
{
"key": "3",
"doc_count": 1,
"max_age": {
"value": 20,
"value_as_string": "20.0"
}
},
{
"key": "4",
"doc_count": 1,
"max_age": {
"value": 16,
"value_as_string": "16.0"
}
}
]
}
2. 總結
本文介紹了ES中的一些常用的聚合API的使用,包括metric、bucketing以及它們的巢狀使用方法。掌握了這些API就可以完成簡單的資料統計功能,更多的API詳見官方文件。前面的部落格中都是介紹了ES的Rest API,接下來的文章中將會介紹Java API的使用,使用Java API可以實現前面介紹的所有API的功能。
相關推薦
ELK第六篇:Aggregations (聚合)REST API的使用
簡介 上一篇部落格介紹了ES中的簡單查詢API的使用,本篇將介紹ES提供的聚合API的使用。ES提供的聚合功能可以用來進行簡單的資料分析。本文仍然以上一篇提供的資料為例來講解。資料如下: studentNo name male age
第六次作業(二)
第六次作業 absolut margin posit logs jpg ng- mage ima div { margin: 20px } #d1 { width: 180px; height: 180px; background-color: yellow; border
第六次作業(3)
cccccc -c mar ima absolute solid .cn abs mage div { margin: 20px } #d1 { width: 180px; height: 200px; background-color: black; border: so
第六節----集合(set)
6.1 設值 Redis 的 Set 是 String 型別的無序集合。集合成員是唯一的,這就意味著集合中不能出現重複的資料。 可以將Redis中的Set理解為Ja
作業系統——第六章筆記(四)
7.緩衝區管理 有”控制器”或”通道”的幫助後CPU可解放去做其他事物,提高了利用率。 但分析單個程式內的執行 CPU計算工作需等待後續資料輸入才可繼續 CPU計算需等待資料輸入完才能計算,雖然資料輸入不需CPU干預,但CPU的解放也只是能去做其他程式,需切換工作,會產生開銷
作業系統——第六章筆記(三)
5.與裝置無關的I/O軟體 5.1裝置獨立性的基本含義: 1)指應用程式中所使用的裝置,不侷限於使用某個具體的物理裝置,也稱為裝置無關性。 2)為了實現裝置獨立性,在裝置驅動程式之上設定一層軟體,稱為與裝置無關的I/O軟體,或裝置獨立性軟體。 3)裝置無關的軟體是I/O系統最高層軟體,但它和
作業系統——第六章筆記(二)
3.中斷機構和中斷處理程式 中斷在作業系統中有特殊而重要的地位,沒有它就不可能實現多道程式。 中斷是I/O系統最低的一層,也是裝置管理的基礎。 3.1中斷簡介 3.1.1中斷和陷入 1)中斷:CPU對I/O裝置發來的中斷訊號的一種響應,中斷是由外部裝置引起的,又稱外中斷。 2)陷入:由CPU
作業系統——第六章筆記(一)
輸入輸出系統——I/O系統 系統管理: 1)管理物件: I/O裝置和相應的裝置控制器(I/O系統組成) 2)基本任務: 完成使用者提出的I/O請求, 提高I/O速率、改善I/O裝置的利用率。 為更高層程序方便使用裝置提供手段 I/O系統的功能、模型和介面 1.1
實時搜尋引擎Elasticsearch(4)——Aggregations (聚合)API的使用
上一篇部落格介紹了ES中的簡單查詢API的使用,本篇將介紹ES提供的聚合API的使用。ES提供的聚合功能可以用來進行簡單的資料分析。本文仍然以上一篇提供的資料為例來講解。資料如下: studentNo name male age birthday
【轉載】SpringCloud教程 | 第四篇:斷路器(Hystrix)
在微服務架構中,根據業務來拆分成一個個的服務,服務與服務之間可以相互呼叫(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign來呼叫。為了保證其高可用,單個服務通常會叢集部署。由於網路原因或者自身的原因,服務並不
史上最簡單的SpringCloud教程 | 第四篇:斷路器(Hystrix)
在微服務架構中,根據業務來拆分成一個個的服務,服務與服務之間可以相互呼叫(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign來呼叫。為了保證其高可用,單個服務通常會叢集部署。由於網路原因或者自身的原因,服務並不能保證100%可用,如果
SpringCloud教程 | 第四篇:斷路器(Hystrix)
在微服務架構中,根據業務來拆分成一個個的服務,服務與服務之間可以相互呼叫(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign來呼叫。為了保證其高可用,單個服務通常會叢集部署。由於網路原因或者自身的原因,服務並不能保證100%可用,
Spring Cloud系列教程 | 第六篇:Spring Cloud Zuul作為API閘道器實現請求路由轉發教程
推薦 Spring Cloud 視訊: Spring Cloud Zuul作為API閘道器實現請求路由轉發教程 當我們的架構實現前後端分離以後,前端和後端之間互動就是通過API閘道器進行,API閘道器兩個職責: 1.設計上的適配層,或稱Facade模
實時搜尋引擎Elasticsearch(2)——Rest API的使用
上一篇文章簡單的介紹了ES的基本概念、安裝執行等內容,本文將介紹ES中的常用Rest API。 ES為開發者提供了非常豐富的基於HTTP協議的Rest API,只需要向ES服務端傳送簡單的Rest請求,就可以實現非常強大的功能。本篇文章主要介紹ES中常用操作的Rest AP
#MINI2440實現語音識別# (三)REST API訪問和VAD端點檢測
1.前言 本文主要是接#MINI2440實現語音識別# (一)整體概述和實現流程記錄這篇文章繼續講。首先簡單介紹下背景。前面三個階段分別完成了嵌入式Linux最小系統移植、驅動UDA1341音效卡、跑通訊飛Demo庫,可以實現語音轉文字,但是存在幾
第六篇-以隱式意圖(Implicit Intent)呼叫系統服務
一、新建一個layout5.xml,同樣換為constriant模式。 二、拖動兩個Button到預覽介面,第一個按鈕名字改為DISPLAY WEBPAGE,第二個按鈕名字改為MAKE A CALL。第一個按鈕連線上左右。width改為match。第二個按鈕連線左右,上方連第一個按鈕的下方。width改為m
第六篇:基本資料型別及用法(3)
集合set 1.集合由不同無序的元素組成,集合中只能存放不可變型別(數字,字串,元祖),例如:s={123,"abc",(1,2,"a")} -重複元素會被去除,所以可用集合去重,例:不考慮順序,去除列表li中重複元素 1 li=["alex",123,"he
「Odoo 基礎教程系列」第六篇——從 Todo 應用開始(5)
大家好鴨,我又來更新啦!還記得我們在第二篇教程中提到過的動作(actions)嗎,今天我們就來專門講講在 Odoo 中的 action,學習不同型別的動作對應的應用場景,並且在我們的 Todo 應用中使用上其中一些型別的動作。 視窗動作 視窗動作在 Odoo 中是
【第六篇】Qt學習與使用---在qt中列印PDF檔案(不是生成PDF)
1、目的 如題,列印pdf檔案中的內容。 2、思路 (1)思路1:可以通過Poppler類來讀取pdf中的內容,並轉化成圖片,再 列印這些圖片。這個方法的瑕疵是,需要在列印的時候準確的寫出一頁圖片在A4紙上的列印座標和大小。否則會導致與原文不同。 (2)思路2:呼叫系統介面,讓win
微服務之SpringCloud架構第六篇(上)——配置中心(Apollo)
隨著程式功能的日益複雜,程式的配置日益增多:各種功能的開關、引數的配置、伺服器的地址…… 並且對配置的期望也越來越高,配置修改後實時生效,灰度釋出,分環境、分叢集管理配置,完善的許可權、稽核機制…… 並且隨著採用分散式的開發模式,專案之間的相互引用隨著服務的不斷增多,相