1. 程式人生 > >Esper學習筆記三:EPL語法(1)

Esper學習筆記三:EPL語法(1)

1.EPL語法簡介

EPL全稱Event Processing Language,是一種類似SQL的語言,包含了SELECT, FROM, WHERE, GROUP BY, HAVING 和 ORDER BY子句,同時用事件流代替了table作為資料來源,並且能像SQL那樣join,filtering和aggregation。除了select,EPL也有insert into,update,delete,不過含義和SQL並不是很接近。另外還有pattern和output子句,這兩個是SQL所沒有的。EPL還定義了一個叫view的東西,類似SQL的table,來決定哪些資料是可用的,Esper提供了十多個view,並且保證這些view可以被重複使用。而且使用者還可以擴充套件view成為自定義view來滿足需求。在view的基礎上,EPL還提供了named window的定義,作用和view類似,但是更加靈活。

2.語法

大部分EPL語句都遵循以下格式

[annotations]
[expression_declarations]
[context context_name]
[insert into insert_into_def]
select select_list
from stream_def [as name] [, stream_def [as name]] [,...]
[where search_conditions]
[group by grouping_expression_list]
[having grouping_search_conditions]
[output output_specification]
[order by order_by_expression_list]
[limit num_rows]

3.時間週期

time-period : [year-part] [month-part] [week-part] [day-part] [hour-part] [minute-part] [seconds-part] [milliseconds-part]

year-part : (number|variable_name) ("years" | "year")
month-part : (number|variable_name) ("months" | "month")
week-part : (number|variable_name) ("weeks" | "week")
day-part : (number|variable_name) ("days" | "day")
hour-part : (number|variable_name) ("hours" | "hour")
minute-part : (number|variable_name) ("minutes" | "minute" | "min")
seconds-part : (number|variable_name) ("seconds" | "second" | "sec")
milliseconds-part : (number|variable_name) ("milliseconds" | "millisecond" | "msec")

時間範圍在EPL中的使用:

select avg(price) from Fruit.win:time(5 minute 3 sec) //在5分3秒中統計price平均值。
select sum(account) from User output every 1 day //每天輸出一次計算結果

Esper規定每月的天數都是30天,所以對準確性要求高的業務,以月為單位進行計算會出現誤差的。

4.註解

EPL也可以寫註解,種類不多,大部分簡單而有效

// 不包含引數或者單個引數的註解
@annotation_name [(annotation_parameters)]
 
// 包含多個屬性名-值對的註解
@annotation_name (attribute_name = attribute_value, [name=value, ...])
 
// 多個註解聯合使用
@annotation_name [(annotation_parameters)] [@annotation_name [(annotation_parameters)]] [...]

具體註解

1)@Name 指定EPL的名稱,引數只有一個。例如:@Name("MyEPL")

2)@Description 對EPL進行描述,引數只有一個。例如:@Description("This is MyEPL")

3)@Tag 對EPL進行額外的說明,引數有兩個分別為Tag的名稱和Tag的值,用逗號分隔。例如:@Tag(name="author",value="luonanqin")

4)@Priority 指定EPL的優先順序,引數只有一個,並且整數(可負可正)。例如:@Priority(10)

5)@Drop 指定事件經過此EPL後不再參與其他的EPL計算,該註解無引數

6)@Hint 為EPL加上某些標記,讓引擎對此EPL產生其他的操作,會改變EPL例項的記憶體佔用,但通常不會改變輸出。其引數固定,由Esper提供

7)@Audit EPL新增此註解後,可以額外輸出EPL執行情況,有點類似日誌的感覺(當然沒有日誌的功能全啦),具體使用場景在此先不提。

8)@Hook 與SQL相關,這裡暫且不說

9)@EventRepresentation 這是用來指定EPL產生的計算結果事件包含的資料形式。引數只有一個,即array=true或array=false。false為預設值,代表資料形式為Map,若為true,則資料形式為陣列。

5.表示式

類似自定義函式,通常用Lambda表示式來建立的(也有別的方法建立),而Lambda表示式就一個“ => ”符號,表示“gose to”。符號的左邊表示輸入引數,符號右邊表示計算過程,計算結果就是這個表示式的返回值,即Expression的返回值。

語法:

expression expression_name { expression_body }

expression是關鍵字,expression_name為expression的名稱(唯一),expression_body是expression的具體內容。

expression_body語法格式:

expression_body: (input_param [,input_param [,...]]) => expression

例如:

expression middle { x => (x.max+x.min)/2 } select middle(apple) from Apple as apple

x表示輸入引數,而x.max和x.min都是x代表的事件流的屬性,如果事件流沒這個屬性,expression的定義就是錯誤的。

express的定義必須在使用它的句子之前完成。使用時直接寫expression的名字和用圓括號包含要計算的引數即可。再次提醒,expression的引數只能是事件流別名,即apple,別名的定義就如上面那樣,事件流之後跟著as,然後再跟別名。

多個expression情況

expression sumage { (x,y) => x.age+y.age } select sumage(me,you) from Me as me, You as you

全域性表示式

對於expression裡用另一個expression,EPL不允許在一個句子裡建立兩個expression,所以就出現了Global-Expression。普通的expression只作用於定義它的epl,如上面所有的包含select子句的epl就是如此。

create expression expression_name { expression_body }

和普通的expression相比,就是多了個create,不過他不能和別的子句放在一起,即他是單獨執行的。

epService.getEPAdministrator().createEPL("create expression avgPrice { x => (x.fist+x.last)/2 }");

在expression使用全域性expression

// 先定義全域性的avgPrice
create expression avgPrice { x => (x.fist+x.last)/2 }
 
// bananaPrice Banana事件中包含了first和last屬性,否則將報錯
expression bananaPrice{ x => avgPrice(x) } select bananaPrice(b) from Banana as b

 

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