Esper学习之六:EPL语法(二)
中秋三天,说闲也不闲,调调工作的代码,倒还解决不少问题。不过也是因为最近工作忙的缘故,Esper被我冷落不少日子了,趁着今天最后一天,赶紧写一篇出来。
从上一篇开始说EPL的语法,主要是关于注解的。今天来说说比较常用的语法,Select Clause和From Clause。这个两个可以说是写EPL必备,要想得到事件流的处理结果,基本上就靠他们俩了(Pattern除外)。今天的内容比较简单,还请各位同学牢记,以免以后应用的时候花时间看文档或者我的文章。
Select Clause
1.查询事件流的所有属性及特定属性
EPL的select和SQL的select很相近,SQL用*表示查询表的所有字段,而EPL用*表示查询事件流的所有属性值。SQL查询某个字段名,直接在select后跟字段名就ok,EPL也是将要查询的属性名放在select之后。若查多个属性值,则用逗号分割。和SQL一样,EPL查询属性也可以设置别名。示例如下:
// EPL:查询完整的User对象
select * from User
// 获取User对象
User u = newEvent.getUnderlying(); // EPL:查询User的name和id,id别名为i
select name, id as i from User
// 获取name和id
String name = (String)newEvent.get("name");
int id = (Integer)newEvent.get("i");
这里要注意,如果查询的是一个完整对象,需要调用getUnderlying()方法,而get方法是针对确定的属性名或者别名。另外*是不能设置别名的。
2.表达式
除了查询完整对象和特定属性,EPL还支持属性值的计算,以计算后的值作为结果返回,并且也能设置别名。这个计算的式子就是表达式。例如:
// 计算长方形的面积(长乘以宽)
select length * width as area from Rectangle
除了简单的加减乘除,还可以利用事件流对象的某个方法。例如:
// 计算长方形的面积(长乘以宽)
select r.getArea(r.length,r.width) as area from Rectangle as r select r.getArea() as area from Rectangle as r
// Rectangle类
public class Rectangle
{
private int length;
private int width; /** 省略getter/setter方法 **/
// 外部传入参数计算面积
public int getArea(int l, int w){
return l*w;
} // 计算该对象的面积
public int getArea(){
return length * width;
}
}
如上所示,一个方法需要传参,另一个方法不需要,但是他会利用当前事件的length和width来计算面积。而且要注意的是事件流需要设置别名才能使用其方法,如:r.getArea()
如果Rectangle类里没有计算面积的方法,但是提供了一个专门计算面积的静态方法,表达式也可以直接引用。不过要事先加载这个包含方法的类。例如:
// 该类用于计算面积
public class ComputeArea{ public static int getArea(int length, int width){
return length*width;
}
} // 加载
epService.getEPAdministrator().getConfiguration().addImport(ComputeArea.class);
// 调用ComputeArea的getArea方法计算面积
select ComputeArea.getArea(length,width) from Rectangle
注意一定要是静态方法,不然没有实例化是没法引用的。
3.多事件流的查询
和SQL类似,EPL也可以同时对多个事件流进行查询,但是必须对每个事件流设置别名。例如:
// 当老师的id和学生的id相同时,查询学生的姓名和老师的姓名
select s.name, t.name from Student as s, Teacher as t where s.id=t.id
如果想查询Student或者Teacher,则EPL改写如下:
select s.* as st, t.* as tr from Student as s, Teacher as t where s.id=t.id
如果想要查询的属性只有存在于一个事件,那么可以不用"别名.属性名",但是最好还是带上别名,万一哪天另一个事件流多了一个一样的属性,那时候不需要修改EPL也可以使用。
4.insert和remove事件流
Esper对于事件流分输入和移出两种,分别对应监听器的两个参数newEvents和oldEvents,关于监听器的内容可参看《Esper学习之三:进程模型》。newEvents通常对应事件的计算结果,oldEvents可以理解过上一次计算结果。默认情况下,只有newEvents有值,oldEvents为null。如果需要查看oldEvents,则需要使用一个参数。例如:
select rstream * from User
如果使用了该参数,则会将上一次计算结果放入newEvents内,而不是oldEvents(以前我还以为这是一个bug,后面发现手册上官方明确就是newEvents,汗!)。并且无法获得当前的计算结果
select irstream * from User
如果使用了该参数,则会将当前的计算结果放入newEvents内,上一次的计算结果放入oldEvents内。
select istream * from User
// 等同于
select * from User
如果使用了该参数,则会将当前的计算结果放入newEvents内,并且无法获得上一次的计算结果。同时该参数也是默认参数,可不写。
如果想修改默认参数,需要调用配置接口修改配置。
5.Distinct
distinct的用法和SQL一样,放在需要修饰的属性或者*前即可。例如:
select distinct * from User.win:time(3 sec)
6.查询指定引擎的处理结果
除了上述所说的一些特点外,select还可以针对某个引擎进行查询。因为引擎都有自己的URI,所以可以在select句子中增加URI标识来指定查询哪一个引擎的事件处理情况。例如:
// 引擎URI为Processor
select Processor.MyEvent.myProperty from Processor.MyEvent
From Clause
1.语法介绍
From的语法不难,主要内容是针对事件流的处理。包括事件流过滤,事件流的维持等等。语法如下:
from stream_def [as name] [unidirectional] [retain-union | retain-intersection] [, stream_def [as stream_name]] [, ...] // 事件流
event_stream_name [(filter_criteria)] [contained_selection] [.view_spec] [.view_spec] [...]
unidirectional,retain-union,retain-intersection,contained_selection,view_spec这几个关键字因为涉及到view的知识,所以这里没法讲解。待学完view之后再来回顾这几个参数会很容易理解的。下面讲讲怎么过滤事件流
2.事件流过滤
2.1.事件属性过滤
事件流过滤通常情况都是对其中某个或多个属性加以限制来达到过滤的目的。注意,过滤表达式是紧跟在事件流名称之后而不是别名之后。例如:
// 只有age大于10的User对象才可查询到name值
select name from User(age>10) as user
// 当name=“luonanqin”时,可获得其age值
select age from User(name="luonanqin") // 错误写法
select name from User as user(age>10)
过滤表达式写法多种多样,可以用符号,又或者使用and,or,between等逻辑语言。例如:
// 查询年龄大于15小于18的学生的姓名
select name from Student(age between 15 and 18)
// 等同于
select name from Student(age >= 15 and age <= 18)
// 等同于
select name from Student(age >= 15, age <= 18)
看以看到,过滤表达式写法很多,并且多个表达式同时作用于一个事件流,用逗号连接即可。如果说满足其中一个条件即可,则需要用or连接。
2.2.过滤范围
刚才说到过滤表达式使用的符号很多,总结下来基本上有<, >, <=, >=, =, !=, between, in, not in, and, or, [ ], ( )。这里主要说下between,in,( ),[ ]
between……and……
和SQL的between……and……意思一样,是一个闭区间。比如说between 10 and 15,中文语义为10到15之间并包含10和15.
( )
表示一个开区间,语法为(low:high)。如(10:15),表示10到15之间,并且不包含10和15
[ ]
表示一个闭区间,语法为[low:high]。如[10:15],表示10到15之间,并且包含10和15
( )和[ ]可以混合用。比如[10:15)或者(10:15]
in
配合( )和[ ]进行使用,表示值在某个范围内。比如:
select name from User(age in [10:15))
相应的,not in表示不在此范围内。
以上都是针对数字的例子,in和not in同样可以作用于字符串。比如:
select age from User(name in ('张三', '李四'))
2.3 静态方法过滤
除了上面说的这些符号以外,类似于select子句中使用的静态方法,过滤表达式中也可以使用,但是返回值必须为布尔值,不然会报错。例如:
// 判断总数是否等于0
public class IsZero
{
public static boolean isZero(int sum)
{
return sum==0;
}
}
// 加载
epService.getEPAdministrator().getConfiguration().addImport(IsZero.class);
// 查询没有钱的用户的name值(User包含name和money属性)
select name from User(IsZero.isZero(money))
事件流的过滤并不能弄得很复杂,他有一下几个限制:
1. 要过滤的属性只能是数字和字符串。
2. 过滤表达式中不能使用聚合函数。
3. “prev”和“prior”函数不能用于过滤表达式(暂且不考虑这是什么)
Select和From的基础内容基本上就是上面所说的。当学过后面的章节之后,select和from可以写得很复杂,才能支持更为复杂的业务需求。特别是学过view和一些event function之后,变化就更加多样了。下一篇将讲解别的Clause,敬请期待。
Esper学习之六:EPL语法(二)的更多相关文章
- Esper学习之十二:EPL语法(八)
今天的内容十分重要,在Esper的应用中是十分常用的功能之一.它是一种事件集合,我们可以对这个集合进行增删查改,所以在复杂的业务场景中我们肯定不会缺少它.它就是Named Window. 由于本篇篇幅 ...
- Esper学习之十一:EPL语法(七)
上一篇说到了EPL如何访问关系型数据库这种数据源,实际上别的数据源,比如:webservice.分布式缓存.非关系型数据库等等,Esper提供了统一的数据访问接口.然后今天会讲解如何创建另外一种事件类 ...
- Esper学习之五:EPL语法(一)
上篇说到了Esper的Context,要是不了解的同学请参看<Esper学习之四:Context>,看过的同学如果还是不理解的话可以给我评论,我将会尽可能的解答.之前有些同学问我Conte ...
- Esper学习之九:EPL语法(五)
本篇的内容主要包括了Subquery(也就是子查询)和Join,内容不少,但是不难,基本上和sql差不太多. 1.Subquery EPL里的Subquery和sql的类似,是否比sql的用法更多我不 ...
- Esper学习之七:EPL语法(三)
1.Aggregation 和SQL一样,EPL也有Aggregation,即聚合函数.语法如下: aggregate_function([all|distinct] expression) aggr ...
- Esper学习之十五:Pattern(二)
上一篇开始了新一轮语法——Pattern的讲解,一开始为大家普及了几个基础知识,其中有说到操作符.当时只是把它们都列举出来了,所以今天这篇就是专门详解这些操作符的,但是由于篇幅限制,本篇先会讲几个,剩 ...
- web前端学习python之第一章_基础语法(二)
web前端学习python之第一章_基础语法(二) 前言:最近新做了一个管理系统,前端已经基本完成, 但是后端人手不足没人给我写接口,自力更生丰衣足食, 所以决定自学python自己给自己写接口哈哈哈 ...
- Esper学习之四:Context
上周末打球实在太累了,就没来得及更新,只是列了个提纲做做准备,发现Context还是有很多内容的.结果也花了不少时间才写完,所以这篇需要各位慢慢消化,并且最好多写几个例子加深理解. 如果有不了解Esp ...
- Esper学习之三:进程模型
之前对Esper所能处理的事件结构进行了概述,并结合了例子进行讲解,不清楚的同学请看Esper学习之二:事件类型.今天主要为大家解释一下Esper是怎么处理事件的,即Esper的进程模型. 1.Upd ...
随机推荐
- HLJOJ1015(多源最短路径失真)
意甲冠军:n,m,k,有着n村.有着k路,每个村都有一个电话亭,现在,我们要建立在村中心展台,快递每一个需要同村的中心村,然后返回报告(有向图),有着m电话,假设村配置的手机,那么你并不需要报告.最低 ...
- 设计模式之八:外观模式(Facade)
外观模式: 为子系统中的一系列接口提供了一个统一的界面.外观模式定义了一个高层次的接口以使子系统更加easy使用. Provide a unified interface to a set of in ...
- 前端JS模版库kino.razor - 原理流程分析 - 改进版轮子RazorJs
1.前言 从后台获取数据,在前端JS里面拼接字符串,不累吗?敢不敢找一款前端使使... 现在这种模板库比较多了,我用过的jquery-template .JsRender .听说过的一堆,还有各种MV ...
- 检测 HTML5\CSS3\JAVASCRIPT 在浏览器的适应情况
CSS3 Selectors Test : 这是CSS3.INFO网站提供的css选择器测试页面,它能够详细显示当前浏览器对所有CSS3选择器的支持情况.启动测试,浏览器会自动测验,并已列表的方式显示 ...
- MVC中的AppendTrailingSlash以及LowercaseUrls
asp.net MVC是一个具有极大扩展性的框架,可以在从Url请求开始直到最终的html的渲染之间进行扩展,所以要学好还是需要了解框架的运行原理,推荐Artech. 今天我们回忆的不是MVC中的fi ...
- django的Model 模型中常用的字段类型
常用的字段类型: AutoField:自增长字段,通常不用,如果未在Model中显示指定主键,django会默认建立一个整型的自增长主键字段 BooleanField:布尔型,值为True或False ...
- React-Native OpenGL体验一
昨天初体验了一把SVG一个并不是多么复杂的动画,我在iOS模拟器上体验的是流畅的,但是在Android真机上体验,还是比较卡的. 下面来介绍一个OpenGL的第三方库: 下面是我运行的里面Demo的效 ...
- PHP学习笔记三十四【记录日志】
<?php function my_error2($errno,$errmes) { echo "错误号:".$errno; //默认时区是格林威治相差八个时区 //设置 1 ...
- pca图像识别
代码下载:基于PCA(主成分分析)的人脸识别 人脸识别是一个有监督学习过程,首先利用训练集构造一个人脸模型,然后将测试集与训练集进行匹配,找到与之对应的训练集头像.最容易的方式是直接利用欧式距离计算测 ...
- iOS-设计模式之通知
通知设计模式简单好用,就是一个项目中如果用的太多,不利于代码维护,可读性太差. 实现过程: [[NSNotificationCenter defaultCenter]postNotificationN ...