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相似,可是更加灵活。express
大部分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]
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中的使用:app
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天,因此对准确性要求高的业务,以月为单位进行计算会出现偏差的。函数
EPL也能够写注解,种类很少,大部分简单而有效ui
// 不包含参数或者单个参数的注解 @annotation_name [(annotation_parameters)] // 包含多个属性名-值对的注解 @annotation_name (attribute_name = attribute_value, [name=value, ...]) // 多个注解联合使用 @annotation_name [(annotation_parameters)] [@annotation_name [(annotation_parameters)]] [...]
具体注解spa
1)@Name 指定EPL的名称,参数只有一个。例如:@Name("MyEPL").net
2)@Description 对EPL进行描述,参数只有一个。例如:@Description("This is MyEPL")日志
3)@Tag 对EPL进行额外的说明,参数有两个分别为Tag的名称和Tag的值,用逗号分隔。例如:@Tag(name="author",value="luonanqin")code
4)@Priority 指定EPL的优先级,参数只有一个,而且整数(可负可正)。例如:@Priority(10)blog
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,则数据形式为数组。
相似自定义函数,一般用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