Esper学习笔记四:EPL语法(2)

1.select

查询所有属性或特定属性

EPL的select和SQL的select很相近,SQL用*表示查询表的所有字段,而EPL用*表示查询事件流的所有属性值。SQL查询某个字段名,直接在select后跟字段名就ok,EPL也是将要查询的属性名放在select之后。若查多个属性值,则用逗号分割。和SQL一样,EPL查询属性也可以设置别名。

//EPL:查询所有属性
select * from myEvent
//在监听器中获取完整对象
MyEvent me = (MyEvent)eb.getUnderlying();

// EPL:查询MyEvent的name和age,age别名为a
select name,age as a from myEvent
//在监听器中获取查询属性
String name = (String)eb.get("name");
Integer a = (Integer)eb.get("a");

表达式

除了查询完整对象和属性外,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来计算面积。而且要注意的是事件流需要设置别名才能使用其方法。

如果Rectangle类里没有计算面积的方法,但是提供了一个专门计算面积的静态方法的工具类,表达式也可以直接引用。不过要事先加载这个包含方法的类。

// 该类用于计算面积
public class ComputeArea{
	
	public static int getArea(int length, int width){
		return length*width;
	}
}
 
// 加载
epService.getEPAdministrator().getConfiguration().addImport(ComputeArea.class);

在EPL中调用计算方法

// 调用ComputeArea的getArea方法计算面积
select ComputeArea.getArea(length,width) from Rectangle

多事件流查询

和SQL中的多表查询类似,EPL也可以同时对多个事件流进行查询,即join,但是必须对每个事件流设置别名。

// 在10秒钟内当老师的id和学生的id相同时,查询学生的姓名和老师的姓名
select s.name, t.name from Student.win:time(10 sec) as s, Teacher.win:time(10 sec) as t where s.id=t.id

如果想查询Student或者Teacher,则EPL改写如下

select s.* as st, t.* as tr from Student.win:time(10 sec) as s, Teacher.win:time(10 sec) as t where s.id=t.id

insert和remove事件流

Esper对于事件流分输入和移出两种,分别对应监听器的两个参数newEvents和oldEvents。

Distinct

去重。

2.From

语法

From的语法不难,主要内容是针对事件流的处理。包括事件流过滤,事件流的维持等等。

事件流过滤

事件流过滤通常情况都是对其中某个或多个属性加以限制来达到过滤的目的。

// 只有age大于10的User对象才可查询到name值
select name from User(age>10) as user
// 当name=''时,可获得其age值
select age from User(name='')

过滤表达式写法多种多样,可以用逗号“,”,又或者使用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)

过滤条件有多种多样,主要有<, >, <=, >=, =, !=, between...and..., in, not in, [ ], ( )。

between...and...

和SQL的between……and……意思一样,是一个闭区间。比如说between 10 and 15,中文语义为10到15之间并包含10和15。

in

配合( )和[ ]进行使用,表示值在某个范围内。

not in

表示不在某个范围内

( ):表示一个开区间,语法为(low:high)。如(10:15),表示10到15之间,并且不包含10和15。

[ ]:表示一个闭区间,语法为[low:high]。如[10:15],表示10到15之间,并且包含10和15

( )和[ ]可以混合用。比如[10:15)或者(10:15]

例如:

select name from User(age in [10:15))
select age from User(name in ('张三', '李四'))

静态方法过滤

除了上面说的这些符号以外,类似于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. 过滤表达式中不能使用聚合函数。

转载:https://blog.csdn.net/luonanqin/article/details/11877127

猜你喜欢

转载自my.oschina.net/u/3100849/blog/1939092