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