摘要:ES中的聚合查詢,類似SQL的 SUM/AVG/COUNT/GROUP BY 分組查詢,主要用于統計分析場景。分組類似SQL的group by語句設定的條件,組內聚合...
ES中的聚合查詢,類似SQL的 SUM/AVG/COUNT/GROUP BY 分組查詢,主要用于統計分析場景。
分組類似SQL的group by語句設定的條件,組內聚合,就是在select編寫的avg、sum、count統計函數;熟悉SQL語句都知道sum、count這些統計函數不一定要跟group by語句配合使用,單獨使用統計函數等同于將所有數據分成一個組,直接對所有數據進行統計。
桶和指標
在ES聚合中滿足特定條件的文檔的集合,叫做桶(桶等同于MySQL中的組),桶的就是一組數據的集合,對數據分組后,得到一組組的數據,就是一個個的桶。
指標指的是對文檔進行統計計算方式,又叫指標聚合。桶內聚合,說的就是先對數據進行分組(分桶),然后對每一個桶內的數據進行指標聚合。說白了就是,前面將數據經過一輪桶聚合,把數據分成一個個的桶之后,我們根據上面計算指標對桶內的數據進行統計。常用的指標有:SUM、COUNT、MAX等統計函數。
借助SQL的統計語句理解桶和指標:
SELECT COUNT(*) FROM shop GROUP BY shop_id
COUNT(*) 相當于指標, 也叫統計指標,GROUP BY shop_id 相當于分桶的條件,也可以叫分組條件,相同shop_id的數據都分到一個桶內。
這條SQL語句的作用就是統計每一個店鋪的訂單數,所以SQL統計的第一步是根據group by shop_id這個條件,把shop_id(店鋪ID)相同的數據分到一個組(桶)里面,然后每一組數據使用count(*)統計函數(指標)計算總數,最終得到每一個店鋪的訂單總數,ES也是類似的過程。
ES聚合查詢語法
{ "aggregations" : { "<aggregation_name>" : { "<aggregation_type>" : { <aggregation_body> } [,"aggregations" : { [<sub_aggregation>]+ } ]? // 嵌套聚合查詢,支持多層嵌套 } [,"<aggregation_name_2>" : { ... } ]* // 多個聚合查詢,每個聚合查詢取不同的名字 } } aggregations - 代表聚合查詢語句,可以簡寫為aggs <aggregation_name> - 代表一個聚合計算的名字,可以隨意命名,因為ES支持一次進行多次統計分析查詢,后面需要通過這個名字在查詢結果中找到我們想要的計算結果。 <aggregation_type> - 聚合類型,代表我們想要怎么統計數據,主要有兩大類聚合類型,桶聚合和指標聚合,這兩類聚合又包括多種聚合類型,例如:指標聚合:sum、avg, 桶聚合:terms、Date histogram等等。 <aggregation_body> - 聚合類型的參數,選擇不同的聚合類型,有不同的參數。 <aggregation_name_2> - 代表其他聚合計算的名字,意思就是可以一次進行多種類型的統計。
例子:
假設存在一個order索引,存儲了每一筆汽車銷售訂單,里面包含了汽車顏色字段color.
POST /shop/_search { "size" : 0, // 設置size=0的意思就是,僅返回聚合查詢結果,不返回普通query查詢結果。 "aggs" : { // 聚合查詢語句的簡寫 "popular_colors" : { // 給聚合查詢取個名字,叫popular_colors "terms" : { // 聚合類型為,terms,terms是桶聚合的一種,類似SQL的group by的作用,根據字段分組,相同字段值的文檔分為一組。 "field" : "color" // terms聚合類型的參數,這里需要設置分組的字段為color,根據color分組 } } } }
上面使用了 terms 桶聚合,而且沒有明確指定指標聚合函數,默認使用的是Value Count聚合指標統計文檔總數, 整個統計的意思是統計每一種汽車顏色的銷量。
等價SQL如下:
select count(color) from shop group by color
查詢結果如下:
{ ... "hits": { // 因為size=0,所以query查詢結果為空 "hits": [] }, "aggregations": { // 聚合查詢結果 "popular_colors": { // 這個就是 popular_colors 聚合查詢的結果,這就是為什么需要給聚合查詢取個名字的原因,如果有多個聚合查詢,可以通過名字查找結果 "buckets": [ // 因為是桶聚合,所以看到返回一個buckets數組,代表分組的統計情況,下面可以看到每一種顏色的銷量情況 { "key": "red", "doc_count": 4 // 紅色的汽車銷量為4 }, { "key": "blue", "doc_count": 2 }, { "key": "green", "doc_count": 2 } ] } } }