ES的Query、Filter、Metric、Bucketing使用詳解

因爲筆者在實際項目僅僅將ES用做索引數據庫,並無深刻研究過ES的搜索功能。並且鑑於筆者的搜索引擎知識有限,本文將僅僅介紹ES簡單(非全文)的查詢API。javascript

筆者本來打算在本文中介紹聚合API的內容,可是寫着寫着發現文章有點過長,不便於閱讀,故將聚合API的內容移至下一篇博客中。html

引言

單單介紹理論和API是乏味和低效率的,本文將結合一個實際的例子來介紹這些API。下表是本文數據表的表結構,表名(type)爲「student」。注意,studentNo是本表的id,也就是_id字段的值與studentNo的值保持一致。java

字段名 字段含義 類型 是否能被索引 備註
studentNo 學號 string id
name 姓名 string  
sex 性別 string  
age 年齡 integer  
birthday 出生年月 date  
address 家庭住址 string  
classNo 班級 string  
isLeader 是否爲班幹部 boolean  

上面的表結構所對應的mapping以下,將數據保存在索引名爲「student」的索引中。正則表達式

{
  "student": { "properties": { "studentNo": { "type": "string", "index": "not_analyzed" }, "name": { "type": "string", "index": "not_analyzed" }, "male": { "type": "string", "index": "not_analyzed" }, "age": { "type": "integer" }, "birthday": { "type": "date", "format": "yyyy-MM-dd" }, "address": { "type": "string", "index": "not_analyzed" }, "classNo": { "type": "string", "index": "not_analyzed " }, "isLeader": { "type": "boolean" } } } }

索引中保存的數據以下,下面介紹的全部API都將基於這個數據表。sql

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

查詢API

ES中的查詢很是靈活,爲用戶提供了很是方便而強大的API。我的以爲ES的調用接口設計得很是好,全部接口合理且風格一致,值得好好研究!shell

Query和Filter

ES爲用戶提供兩類查詢API,一類是在查詢階段就進行條件過濾的query查詢,另外一類是在query查詢出來的數據基礎上再進行過濾的filter查詢。這兩類查詢的區別是:數據庫

  • query方法會計算查詢條件與待查詢數據之間的相關性,計算結果寫入一個score字段,相似於搜索引擎。filter僅僅作字符串匹配,不會計算相關性,相似於通常的數據查詢,因此filter得查詢速度比query快。
  • filter查詢出來的數據會自動被緩存,而query不能。

query和filter能夠單獨使用,也能夠相互嵌套使用,很是靈活。api

Query查詢

下面的狀況下適合使用query查詢:緩存

  • 須要進行全文搜索。
  • 查詢結果依賴於相關性,即須要計算查詢串和數據的相關性。

(1)Match All Querymarkdown

查詢全部的數據,至關於不帶條件查詢。下面的代碼是一個典型的match_all查詢的調用方式。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "query": { "match_all": {} } } '

 

查詢結果以下。其餘全部的查詢都是返回這種格式的數據。

{
  "took": 156, // 查詢耗時(毫秒) "timed_out": false, // 是否超時 "_shards": { "total": 5, // 總共查詢的分片數 "successful": 5, // 查詢成功的分片數 "failed": 0 // 查詢失敗的分片數 }, "hits": { "total": 8, // 本次查詢的記錄數 "max_score": 1, // 查詢全部數據中的最大score "hits": [ // 數據列表 { "_index": "student", // 數據所屬的索引名 "_type": "student", // 數據所屬的type "_id": "4", // 數據的id值 "_score": 1, // 該記錄的score "_source": { // ES將原始數據保存到_source字段中 "studentNo": "4", "name": "張飛", "male": "男", "age": "20", "birthday": "1989-07-30", "classNo": "3", "isLeader": "F" } }, { …… // 其餘的數據格式相同,就不列出來了 } ] } }

 

查詢時,你會發現不管數據量有多大,每次最多隻能查到10條數據。這是由於ES服務端默認對查詢結果作了分頁處理,每頁默認的大小爲10。若是想本身指定查詢的數據,可以使用from和size字段,而且按指定的字段排序。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "query": { "match_all": {} }, "from": 2, // 從2條記錄開始取 "size": 4, // 取4條數據 "sort": { "studentNo": { // 按studentNo字段升序 "order": "asc"// 降序爲desc } } } '

注意:不要把from設得過大(超過10000),不然會致使ES服務端因頻繁GC而沒法正常提供服務。其實實際項目中也沒有誰會翻那麼多頁,可是爲了ES的可用性,務必要對分頁查詢的頁碼作必定的限制。

(2)term query

詞語查詢,若是是對未分詞的字段進行查詢,則表示精確查詢。查找名爲「諸葛亮」的學生,查詢結果爲學號爲5的記錄。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "query": { "term": { "name": "諸葛亮" } } } '

(3)Bool Query

Bool(布爾)查詢是一種複合型查詢,它能夠結合多個其餘的查詢條件。主要有3類邏輯查詢:

  • must:查詢結果必須符合該查詢條件(列表)。
  • should:相似於in的查詢條件。若是bool查詢中不包含must查詢,那麼should默認表示必須符合查詢列表中的一個或多個查詢條件。
  • must_not:查詢結果必須不符合查詢條件(列表)。

查找2班的班幹部,查詢結果爲學號爲5的記錄。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "query": { "bool": { "must": [ { "term": { "classNo": "2" } }, { "term": { "isLeader": "true" } } ] } } } '

(4)Ids Query

id字段查詢。查詢數據id值爲1和2的同窗,因爲id的值與studentNo相同,故查詢結果爲學號爲1和2的學生。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "query": { "ids": { "type": "student", "values": [ "1", "2" ] } } } '

 

(5)Prefix Query

前綴查詢。查找姓【趙】的同窗,查詢結果是學號爲8的趙雲。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "query": { "prefix": { "name": "趙" } } } '

(6)Range Query

範圍查詢,針對date和number類型的數據。查找年齡到18~20歲的同窗,查詢結果是學號爲三、四、五、7的記錄。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "query": { "range": { "age": { "gte": "18", // 表示>= "lte": "20" // 表示<= } } } } '

實際上,對於date類型的數據,ES中以其時間戳(長整形)的形式存放的。

(7)Terms Query

多詞語查詢,查找符合詞語列表的數據。若是要查詢的字段索引爲not_analyzed類型,則terms查詢很是相似於關係型數據庫中的in查詢。下面查找學號爲1,3的學生。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "query": { "terms": { "studentNo": [ "1", "3" ] } } } '

 

(8)Wildcard Query

通配符查詢,是簡化的正則表達式查詢,包括下面兩類通配符:

  • * 表明任意(包括0個)多個字符
  • ? 表明任意一個字符

查找名字的最後一個字是「亮」的同窗,查詢結果是學號爲5的諸葛亮。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "query": { "wildcard": { "name": "*亮" } } } '

 

(9)Regexp Query同窗

正則表達式查詢,這是最靈活的字符串類型字段查詢方式。查找家住長沙市的學生,查詢結果爲學號爲1的學生。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "query": { "regexp": { "address": ".*長沙市.*" // 這裏的.號表示任意一個字符 } } } '

 

Filter查詢

下面的狀況下適合使用filter查詢:

  • yes/no的二元查詢
  • 針對精確值進行查詢

filter和query的查詢方式有很多是重疊的,因此本節僅僅介紹API的調用,一些通用的注意的事項就再也不重複了。

(1)Term Filter

詞語查詢,若是是對未分詞的字段進行查詢,則表示精確查詢。查找名爲「諸葛亮」的學生,查詢結果爲學號爲5的記錄。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "filter": { "term": { "name": "諸葛亮", "_cache" : true // 與query主要是這裏的區別,能夠設置數據緩存 } } } '

filter查詢方式均可以經過設置_cache爲true來緩存數據。若是下一次剛好以相同的查詢條件進行查詢而且該緩存沒有過時,就能夠直接從緩存中讀取數據,這樣就大大加快的查詢速度。

(2)Bool Filter

查找2班的班幹部,查詢結果爲學號爲5的記錄。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "filter": { "bool": { "must": [ { "term": { "classNo": "2" } }, { "term": { "isLeader": "true" } } ] } } } '

(3)And Filter

And邏輯鏈接查詢,鏈接1個或1個以上查詢條件。它與bool查詢中的must查詢很是類似。實際上,and查詢能夠轉化爲對應的bool查詢。查找2班的班幹部,查詢結果爲學號爲5的學生。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "filter": { "and": [ { "term": { "classNo": "2" } }, { "term": { "isLeader": "true" } } ] } } '

(4)Or Filter

Or鏈接查詢,表示邏輯或。。查找2班或者是班幹部的學生名單,查詢結果爲學號爲一、二、五、8的學生。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "filter": { "or": [ { "term": { "classNo": "2" } }, { "term": { "isLeader": "true" } } ] } } '

(5)Exists Filter

存在查詢,查詢指定字段至少包含一個非null值的數據。若是字段索引爲not_analyzed類型,則查詢sql中的is not null查詢方式。查詢地址存在學生,查詢結果爲除了6以外的全部學生。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "filter": { "exists": { "field": "address" } } } '

(6)Missing Filter

缺失值查詢,與Exists查詢正好相反。查詢地址不存在的學生,查詢結果爲學號爲6的學生。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "filter": { "missing": { "field": "address" } } } '

(7)Prefix Filter

前綴查詢。查找姓【趙】的同窗,查詢結果是學號爲8的趙雲。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "filter": { "prefix": { "name": "趙" } } } '

 

(8)Range Filter

範圍查詢,針對date和number類型的數據。查找年齡到18~20歲的同窗,查詢結果是學號爲三、四、五、7的記錄。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "filter": { "range": { "age": { "gte": "18", "lte": "20" } } } } '

 

(9)Terms Filter

多詞語查詢,查找符合詞語列表的數據。若是要查詢的字段索引爲not_analyzed類型,則terms查詢很是相似於關係型數據庫中的in查詢。下面查找學號爲1,3的學生。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "filter": { "terms": { "studentNo": [ "1", "3" ] } } } '

 

(10)Regexp Filter

正則表達式查詢,是最靈活的字符串類型字段查詢方式。查找家住長沙市的學生,查詢結果爲學號爲1的學生。

curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "filter": { "regexp": { "address": ".*長沙市.*" } } } '

 

Aggregations (聚合)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

本文的主要內容有:

  1. metric API的使用
  2. bucketing API的使用
  3. 兩類API的嵌套使用

1. 聚合API

ES中的Aggregations API是從Facets功能基礎上發展而來,官網正在進行替換計劃,建議用戶使用Aggregations API,而不是Facets API。ES中的聚合上能夠分爲下面兩類:

  1. metric(度量)聚合:度量類型聚合主要針對的number類型的數據,須要ES作比較多的計算工做
  2. 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" } } }

 

上面的聚合查詢有兩個要注意的點:

  1. 能夠經過query先過濾數據
  2. 返回的結果會包含聚合操做所做用的數據全集

有時候咱們對做用的數據全集並不太敢興趣,咱們僅僅須要最終的聚合結果。能夠經過查詢類型(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~1八、19~2一、22~2四、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權威指南
相關文章
相關標籤/搜索