Esper學習筆記五:EPL語法(3)

1.Aggregation

相似於SQL中的聚合函數,EPL中聚合函數格式以下:express

aggregate_function([all|distinct] expression)

aggregate_function就是聚合函數的名字,好比avg,sum等。expression一般是事件流的某個屬性,也能夠是不一樣事件流的多個屬性,或者是屬性和常量、函數之間的運算。函數

// 查詢最新5秒的Apple的平均價格
select avg(price) as aPrice from Apple.win:time(5 sec)
 
// 查詢最新10個Apple的價格總和的兩倍
select sum(price*2) as sPrice from Apple.win:length(10)
 
// 查詢最新10個Apple的價格,並用函數計算後再算平均值
select avg(Compute.getResult(price)) from Apple.win:length(10)

函數只能是靜態方法,普通方法不可用。即便是事件流裏包含的靜態方法,也必須用「類名.方法名」的方式進行引用。ui

可使用distinct關鍵字對expression加以約束,表示去掉expression產生的重複的值。默認狀況下爲all關鍵字,即全部的expression值都參與聚合運算。spa

// 查詢最新5秒的Apple的平均價格
select avg(distinct price) as aPrice from Apple.win:time(5 sec)
 
// 假如:5秒內進入了三個Apple事件,price分別爲2,1,2。則針對該EPL的平均值爲(2+1)/2=1.5。由於有distinct的修飾,因此第二個2不參與運算,事件總數即爲2,而不是3。

以上就是聚合函數的使用方法,除此以外須要注意一下幾點.net

1.聚合函數能用於Select和Having,可是不能用於Where設計

2.sum,avg,media,stddev,avedev只能計算數值,至於media,stddev和avedev表明什麼意思,請自行百度。code

3.Esper會忽略expression爲null不讓參與聚合運算,可是count函數除外,即便是null也認爲是一個事件。若是事件流集合中沒有包含任何事件,或者包含的事件中用於聚合計算的expression都是null(好比收集5秒內進入的事件即爲一個事件流集合),則全部聚合函數都返回null。對象

2.Group by

Group by一般配合聚合函數使用。語法和SQL基本同樣,產生的效果就是以某一個或者多個字段進行分組,而後使聚合函數做用於不一樣組的數據。blog

使用group by 要注意一下幾點:事件

1.Group by後面的內容不能包含聚合函數

2.Group by後面的內容不能是以前select子句中聚合函數修飾的屬性名

3.一般狀況要保證分組數量有限制,以防止內存溢出。可是若是分組分了不少,就須要使用@Hint加以控制。

group by 基本用法

// 根據color和size來對10個Apple事件進行分組計算平均price
select avg(price) as aPrice, color, size from Apple.win:length_batch(10) group by color,size

上面例子對color,size同時進行分組,及只有color和size都相同的事件進行統計平均price。

// 根據size來對10個Apple事件進行分組計算平均price和color
select avg(price) as aPrice, color, size from Apple.win:length_batch(10) group by size

只對size進行分組,只要size同樣的事件都進行分組計算。

/ 根據size乘color來對10個Apple事件進行分組計算平均price
select avg(price) as aPrice, size*color from Apple.win:length_batch(10) group by size*color

group by的對象只是一個值,以相同的值進行分組,因此上面和和普通的屬性字段同樣,計算一個值進行分組。若是group by後面的表達式值爲null,則全部爲null的事件都被分爲一組進行計算。

3.@Hint

@Hint是Esper中註解的其中一個它是專用於Group by的。咱們平時使用Group by的時候,會遇到分組數量太多的狀況。好比以時間單位進行分組,那麼內存使用必定是一個大問題。所以@Hint爲其設計了兩個屬性,用於限制Group by的生存時間,使虛擬機能及時回收內存。這兩個屬性分別爲reclaim_group_aged和reclaim_group_freq。

reclaim_group_aged

該屬性後面跟着的是正整數,以秒爲單位,表示在n秒內,若分組的數據沒有進行更新,則分組數據被Esper回收。

// 根據color對10秒內進入的Apple事件進行分組計算平均price,而且對5秒內沒有數據更新的分組進行回收
@Hint('reclaim_group_aged=5')select avg(price) as aPrice, color from Apple.win:time(10 sec) group by color //括號內可使單引號也能夠是雙引號

reclaim_group_freq

該屬性後面跟着的是正整數,以秒爲單位,表示每n秒清理一次分組,可清理的分組是reclaim_group_aged決定的,也就是說要使用該參數,就要配合reclaim_group_aged一塊兒使用。

// 根據color對10秒內進入的Apple事件進行分組計算平均price。對8秒內沒有數據更新的分組進行回收,回收頻率每2秒回收一次
@Hint('reclaim_group_aged=8,reclaim_group_freq=2')select avg(price) as aPrice, color from Apple.win:time(10 sec) group by color

若是不使用reclaim_group_freq屬性,則默認值和reclaim_group_aged的值同樣,對上面來講就是回收的條件爲8秒內沒有數據更新,且每8秒回收一次。這樣的話有可能出現這麼一種狀況,上一個8秒的某個分組在下一個8秒還沒到達時就已經持續8秒沒有數據更新了(這句話會不會有點繞?),可是必須等到回收的時間點到達時才能回收這個分組。在分組產生很快的狀況下,這樣的回收不及時極可能會形成內存溢出。reclaim_group_freq正是爲這種狀況作準備,回收的頻率高一些,在必定程度上能提升內存的使用率。

4.Having

Having的用法和SQL同樣,後面跟的是對聚合函數的計算結果進行過濾。Where子句不能包含聚合函數,因此就由Having來完成。

//根據name進行分組,計算8秒內price的平均值,而且排除平均price小於或等於5的事件。
@Hint('reclaim_group_aged=8,reclaim_group_freq=2')select avg(price) as p,name,age  from myEvent.win:time(8 sec) group by name having avg(price) > 5

Having後面能夠跟多個判斷式子,而且用and,or或者not進行鏈接。

//獲取8秒內平均price大於4而且平均age大於27的事件記錄。
select avg(price) as p,name,age  from myEvent.win:time(8 sec) having avg(price) > 4 and avg(age) > 27

5.Output

Output是EPL中很是有用的東西,用來控制Esper對事件流計算結果的輸出時間和形式,能夠以固定頻率,也能夠是某個時間點輸出。

output [all | first | last | snapshot] every time_period | output_rate events

每隔指定時間輸出結果

// 30分鐘內,每進入一個OrderEvent,統計一次sum price,而且每60秒輸出一次統計結果。
select sum(price) from OrderEvent.win:time(30 min) output snapshot every 60 seconds

指定數量事件以後,開始輸出結果

// 統計20個Apple事件的sum price,而且在有5個Apple事件進入後纔開始輸出統計結果
select sum(price) from Apple.win:length(20) output after 5 events

指定時間以後,每隔多少時間輸出一次結果。

/ 從EPL可用開始計時,通過1分鐘後,每5秒輸出一次當前100秒內的全部Banana的avg price(即:第一次輸出在65秒時)
select avg(price) from Banana.win:time(100 sec) after 1 min snapshot every 5 sec

輸出每兩個事件中的第一個事件結果

select avg(price) as p,name,age  from myEvent.win:time(10 sec) output first every 2 events

輸出每兩個事件中的最後一個事件結果

select avg(price) as p,name,age  from myEvent.win:time(10 sec) output last every 2 events

每進入兩個事件,就輸出窗口內的全部事件

select avg(price) as p,name,age  from myEvent.win:time(10 sec) output snapshot every 2 events

每進入倆個事件,就輸出窗口內的全部事件,並清空窗口內事件

select avg(price) as p,name,age  from myEvent.win:time(5 sec) output all every 2 events

配置定時規則,定時輸出數據

// 在8點到17點這段時間內,每15分鐘輸出一次
select * from Fruit output at (*/15,8:17,*,*,*)

6.when

當達到指定條件時,輸出以前進入引擎的全部事件。

 

轉載:https://blog.csdn.net/luonanqin/article/details/12224303

相關文章
相關標籤/搜索