1. Pattern Atoms and Pattern operators
Pattern是通过原子事件和操作符组合在一起构成模板。原子事件有3类,操作符有4类,具体如下:

原子事件:
1). 普通事件:包括POJO,Map,Array,XML
2). 时间事件:包括间隔n个时间单位、crontab
3). 自定义插件:用于观察特定事件的发生

操作符:
1). 重复操作符:every, every-distinct, [num] and until
2). 逻辑操作符:and, or, not
3). 顺序操作符:->(Followed by)
4). 事件生命周期操作符:timer:within, timer:withinmax, while-expression, 自定义插件

关于操作符,自然会有优先级,具体如下:

Precedence Operator Description Example
1

guard postfix

where timer:within and while (expression) (incl. withinmax and plug-in pattern guard)

MyEvent where timer:within(1 sec)

2

unary

every, not every, distinct

every MyEvent
timer:interval(5 min) and not MyEvent

3 repeat [num], until

[5] MyEvent

[1..3] MyEvent until MyOtherEvent

4 and and every (MyEvent and MyOtherEvent)
5 or or every (MyEvent or MyOtherEvent)
6 followed by -> every (MyEvent -> MyOtherEvent)

上面的内容各位可以先有个印象,方便理解之后的详解。

2. Pattern Filter Expression
Pattern的Filter表达式和普通的表达式没有区别,我就不展开讲解了,各位看看下面几个例子就好,除了Filter之外的东西暂时不用关心是什么意思。

1). every e1=RfidEvent -> e2=RfidEvent(assetId=e1.assetId)
2). every e1=RfidEvent -> e2=RfidEvent(MyLib.isInRadius(e1.x, e1.y, x, y) and zone in (1, e1.zone))
3). every (RfidEvent(zone > 1) and RfidEvent(zone < 10))

3. Controlling Event Consumption
       上面说到了Filter,因为Pattern可以由多个原子事件组成,那么Filter自然也会有多个,正常情况下,所有的Filter都会对进入引擎的事件进行判定,但是我们也有只需要判定一次的时候,只要满足了某个Filter,那么其他的Filter就不用管这个事件了。Esper考虑到了这个需求,我们只需要在Filter表达式后面加个@consume注解即可,此注解可以跟随数字,表示过滤的优先级。默认优先级为1,数值越大优先级越高。

为了结合上面几节的知识,我给了个完整的实例:

  1. package example;
  2. import com.espertech.esper.client.EPAdministrator;
  3. import com.espertech.esper.client.EPRuntime;
  4. import com.espertech.esper.client.EPServiceProvider;
  5. import com.espertech.esper.client.EPServiceProviderManager;
  6. import com.espertech.esper.client.EPStatement;
  7. import com.espertech.esper.client.EventBean;
  8. import com.espertech.esper.client.UpdateListener;
  9. /**
  10. * Created by Luonanqin on 8/11/14.
  11. */
  12. class ConsumeEvent {
  13. private int id;
  14. private String name;
  15. private int age;
  16. public int getId() {
  17. return id;
  18. }
  19. public void setId(int id) {
  20. this.id = id;
  21. }
  22. public String getName() {
  23. return name;
  24. }
  25. public void setName(String name) {
  26. this.name = name;
  27. }
  28. public int getAge() {
  29. return age;
  30. }
  31. public void setAge(int age) {
  32. this.age = age;
  33. }
  34. public String toString() {
  35. return "ConsumeEvent{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';
  36. }
  37. }
  38. class PatternConsumeListener1 implements UpdateListener {
  39. public void update(EventBean[] newEvents, EventBean[] oldEvents) {
  40. if (newEvents != null) {
  41. for (int i = 0; i < newEvents.length; i++) {
  42. System.out.println("a: " + newEvents[i].get("a"));
  43. System.out.println("b: " + newEvents[i].get("b"));
  44. }
  45. }
  46. }
  47. }
  48. class PatternConsumeListener2 implements UpdateListener {
  49. public void update(EventBean[] newEvents, EventBean[] oldEvents) {
  50. if (newEvents != null) {
  51. for (int i = 0; i < newEvents.length; i++) {
  52. System.out.println("a: " + newEvents[i].get("a"));
  53. System.out.println("b: " + newEvents[i].get("b"));
  54. System.out.println("c: " + newEvents[i].get("c"));
  55. }
  56. }
  57. }
  58. }
  59. public class PatternConsumeTest {
  60. public static void main(String[] args) {
  61. EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
  62. EPAdministrator admin = epService.getEPAdministrator();
  63. EPRuntime runtime = epService.getEPRuntime();
  64. String consume = ConsumeEvent.class.getName();
  65. String epl1 = "every (a=" + consume + "(id = 1)@consume and b=" + consume + "(name = 'luonq'))";
  66. System.out.println("EPL1: " + epl1 + "\n");
  67. EPStatement stat1 = admin.createPattern(epl1);
  68. stat1.addListener(new PatternConsumeListener1());
  69. ConsumeEvent ce1 = new ConsumeEvent();
  70. ce1.setId(1);
  71. ce1.setName("luonq");
  72. System.out.println("Send Event: " + ce1);
  73. runtime.sendEvent(ce1);
  74. System.out.println();
  75. ConsumeEvent ce2 = new ConsumeEvent();
  76. ce2.setId(2);
  77. ce2.setName("luonq");
  78. System.out.println("Send Event: " + ce2);
  79. runtime.sendEvent(ce2);
  80. stat1.destroy();
  81. System.out.println();
  82. String epl2 = "every (a=" + consume + "(id = 1)@consume(2) or b=" + consume + "(name = 'luonq')@consume(3) or c=" + consume + "(age > 2))";
  83. System.out.println("EPL2: " + epl2 + "\n");
  84. EPStatement stat2 = admin.createPattern(epl2);
  85. stat2.addListener(new PatternConsumeListener2());
  86. ConsumeEvent ce3 = new ConsumeEvent();
  87. ce3.setId(1);
  88. ce3.setName("luonq");
  89. ce3.setAge(3);
  90. System.out.println("Send Event: " + ce3);
  91. runtime.sendEvent(ce3);
  92. ConsumeEvent ce4 = new ConsumeEvent();
  93. ce4.setId(1);
  94. ce4.setName("luonqin");
  95. ce4.setAge(1);
  96. System.out.println("Send Event: " + ce4);
  97. runtime.sendEvent(ce4);
  98. ConsumeEvent ce5 = new ConsumeEvent();
  99. ce5.setId(3);
  100. ce5.setName("luonqin");
  101. ce5.setAge(5);
  102. System.out.println("Send Event: " + ce5);
  103. runtime.sendEvent(ce5);
  104. }
  105. }

执行结果:

  1. EPL1: every (a=example.ConsumeEvent(id = 1)@consume and b=example.ConsumeEvent(name = 'luonq'))
  2. Send Event: ConsumeEvent{id=1, name='luonq', age=0}
  3. Send Event: ConsumeEvent{id=2, name='luonq', age=0}
  4. a: ConsumeEvent{id=1, name='luonq', age=0}
  5. b: ConsumeEvent{id=2, name='luonq', age=0}
  6. EPL2: every (a=example.ConsumeEvent(id = 1)@consume(2) or b=example.ConsumeEvent(name = 'luonq')@consume(3) or c=example.ConsumeEvent(age > 2))
  7. Send Event: ConsumeEvent{id=1, name='luonq', age=3}
  8. a: null
  9. b: ConsumeEvent{id=1, name='luonq', age=3}
  10. c: null
  11. Send Event: ConsumeEvent{id=1, name='luonqin', age=1}
  12. a: ConsumeEvent{id=1, name='luonqin', age=1}
  13. b: null
  14. c: null
  15. Send Event: ConsumeEvent{id=3, name='luonqin', age=5}
  16. a: null
  17. b: null
  18. c: ConsumeEvent{id=3, name='luonqin', age=5}

这里先简单说明下,every关键字表示引擎把每个事件都进行Pattern的匹配,而不管上一个匹配是否完成。or和and就是或和且的意思,表示满足某个以及满足所有。

去掉consume的执行结果:

  1. EPL1: every (a=example.ConsumeEvent(id = 1) and b=example.ConsumeEvent(name = 'luonq'))
  2. Send Event: ConsumeEvent{id=1, name='luonq', age=0}
  3. a: ConsumeEvent{id=1, name='luonq', age=0}
  4. b: ConsumeEvent{id=1, name='luonq', age=0}
  5. Send Event: ConsumeEvent{id=2, name='luonq', age=0}
  6. EPL2: every (a=example.ConsumeEvent(id = 1) or b=example.ConsumeEvent(name = 'luonq') or c=example.ConsumeEvent(age > 2))
  7. Send Event: ConsumeEvent{id=1, name='luonq', age=3}
  8. a: ConsumeEvent{id=1, name='luonq', age=3}
  9. b: null
  10. c: null
  11. Send Event: ConsumeEvent{id=1, name='luonqin', age=1}
  12. a: ConsumeEvent{id=1, name='luonqin', age=1}
  13. b: null
  14. c: null
  15. Send Event: ConsumeEvent{id=3, name='luonqin', age=5}
  16. a: null
  17. b: null
  18. c: ConsumeEvent{id=3, name='luonqin', age=5}

上面的例子可能看得不是很懂,不过没关系,等到后面讲操作符进行详解后再来回顾就很简单了。

Esper学习之十四:Pattern(一)的更多相关文章

  1. python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例

    python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例 新浪爱彩双色球开奖数据URL:http://zst.aicai.com/ssq/openInfo/ 最终输出结果格 ...

  2. Linux学习之十四、管线命令

    Linux学习之十四.管线命令 地址:http://vbird.dic.ksu.edu.tw/linux_basic/0320bash_6.php

  3. 风炫安全WEB安全学习第二十四节课 利用XSS钓鱼攻击

    风炫安全WEB安全学习第二十四节课 利用XSS钓鱼攻击 XSS钓鱼攻击 HTTP Basic Authentication认证 大家在登录网站的时候,大部分时候是通过一个表单提交登录信息. 但是有时候 ...

  4. Esper学习之十二:EPL语法(八)

    今天的内容十分重要,在Esper的应用中是十分常用的功能之一.它是一种事件集合,我们可以对这个集合进行增删查改,所以在复杂的业务场景中我们肯定不会缺少它.它就是Named Window. 由于本篇篇幅 ...

  5. (C/C++学习笔记) 十四. 动态分配

    十四. 动态分配 ● C语言实现动态数组 C语言实现动态数组,克服静态数组大小固定的缺陷 C语言中,数组长度必须在创建数组时指定,并且只能是一个常数,不能是变量.一旦定义了一个数组,系统将为它分配一个 ...

  6. Esper学习之十五:Pattern(二)

    上一篇开始了新一轮语法——Pattern的讲解,一开始为大家普及了几个基础知识,其中有说到操作符.当时只是把它们都列举出来了,所以今天这篇就是专门详解这些操作符的,但是由于篇幅限制,本篇先会讲几个,剩 ...

  7. Esper学习之十:EPL语法(六)

    在esper的文档中,epl访问数据库的配置放在了比较靠后的位置,不过为了方便各位学习,这里会先说明和数据库交互的相关配置,然后再说epl怎么访问数据库. 配置文件在官方esper包的etc文件夹下, ...

  8. javascript基础学习(十四)

    javascript之表单对象 学习要点: 表单对象 文本框 按钮 单选框和复选框 一.表单对象 在HTML文档中可能会出现多个表单,也就是说,一个HTML文档中可能出现多个<form>标 ...

  9. JMeter学习(十四)JMeter函数学习(转载)

    转载自 http://www.cnblogs.com/yangxia-test JMeter函数是一些能够转化在测试树中取样器或者其他配置元件的域的特殊值.一个函数的调用就像这样:${_functio ...

随机推荐

  1. nodejs基础 -- 路由

    我们要为路由提供请求的URL和其他需要的GET/POST参数,随后路由需要根据这些数据(URL.GET/POST参数)来执行相应的代码. 因此,需要查看HTTP请求,从中提取出请求的URL及GET/P ...

  2. Js正则校验身份证号码

    原文链接:http://gongwen.sinaapp.com/article-126-cmd 这个其实不难,在网上多找一下总会有意外收获的.但是工欲善其事,必先利其器.我们需要了解一下身份证号的规则 ...

  3. k8s sidecar, Ambassador, Adapter containers

    When you start thinking in terms of Pods, there are naturally some general patterns of modular appli ...

  4. SpringCloud 集锦

    一.SpringCloud和Dubbo SpringCloud整合了一套较为完整的微服务解决方案框架,而Dubbo只是解决了微服务的几个方面的问题. content Dubbo SpringCloud ...

  5. WPF TextBox属性IsReadOnlyCaretVisible

    纠结了半天WPF下只读的TextBox怎么显示输入焦点提示,发现wpf 4中已有新属性“IsReadOnlyCaretVisible”,大善^_^

  6. javascript报错集锦

    1.JS 异常之 missing ) after argument list 错误释疑报错原因:不是字符串就输出啦

  7. Mapper method 'com.autoyol.mapper.trans.AccountLogMapper.getTotalIncomByMemNoLastest attempted to return null from a method with a primitive return type (int).解决方法

    1.打开日志输出,降低日志级别. <AppenderRef ref="console" level="trace"></AppenderRef ...

  8. C++标准命名空间std

    输入输出要用到这个. 标准C++库的所有的标识符都是在一个名为std的命名空间中定义的,或者说标准头文件(如iostream)中函数.类.对象和类模板是在命名空间 std中定义的.std是standa ...

  9. Thinkphp 模板中使用自定义函数的方法

    1.number_format {$number|number_format=2}   千分位,保留两位小数 2.round {$number|round=2}   四舍五入保留两位小数

  10. 解决sourcesafe admin用户自动登录并且不用密码的问题

    用管理员(admin)登录Microsoft   Visual   SourceSafe   Administration tools-> "SourceSafe   Options界 ...