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 ...
随机推荐
- JConsole 连接配置
远程监控配置 JDK配置 在%JAVA_HOME%/jre/lib/management目录下,jmxremote.password.template.jmxremote.password需要修改配置 ...
- 【Spark Core】任务运行机制和Task源代码浅析1
引言 上一小节<TaskScheduler源代码与任务提交原理浅析2>介绍了Driver側将Stage进行划分.依据Executor闲置情况分发任务,终于通过DriverActor向exe ...
- 学习Swift中的CoreImage(图形核心编程)
Core Image是一个可以让你轻松使用图形过虑器的强力框架.在这里你几乎可以获得所有不同种类的效果,比如修改图像饱和度,色彩范围,亮度等.它甚至也可以利用CPU或者GPU来处理图像数据并且它的速度 ...
- Linux下Samba的配置
前言: 为了实现windows 和 Linux以及其它操作系统之间的资源共享,软件商推出nfs 和samba两种解决方案.因为市场上缺乏象pc-nfs那样的client工具,使得Linux和windo ...
- EffectiveC#1--尽可能的使用属性(property),而不是数据成员(field)
1.属性可以进行数据绑定 2.可以做数据安全校验.在对数据检测时,如果发现数据不满足条件,最好以抛出异常的形式来解决 如下代码不可取 public string Name { get { if(thi ...
- javascript延迟加载及异步(defer和async)
一直以来写代码的时候的常用习惯就是吧所有的js文件直接加载在文档的head标签里面,在写js文件的时候有时候获取一些文件对象的时候为空对象,这是由于文档结构还没有加载完,但是js文件已经加载完.也就是 ...
- CDZSC_2015寒假新人(2)——数学 A
A - A Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status ...
- deepin软件中心打不开
想体验下deepin新特性,就修改了软件源为test版本,结果就坑了,软件中心打不开了...无奈之下,看了下论坛,找到了官方源地址,然后替换. sudo gedit /etc/apt/sources. ...
- 负载均衡集群之LVS算法和模型
LVS-->Linux Virtual Server 实现算法-->静态/动态,共10种 静态算法: rr(round robin): 解析:轮叫算法,即0-9循环 ...
- pubwin会员合并
此博文已移至爬不稳独立博客:www.pubwin2009.net连接:http://www.pubwin2009.net/index.php/post/15.html 我们说下过程(这里,我们要求两个 ...