Esper事件处理引擎_16_EPL 语法_8_NamedWindow

官方地址:http://www.espertech.com


Esper 事件引擎栏目:http://blog.csdn.net/xiaohulunb/article/category/2436609


EPL 语法代码见-GitHub代码地址:点击打开链接


涉及 Javabean,Listener,main 以 GitHub 包下为最新更,注释解释排版有问题可参考源码


EPL_8_NamedWindow


package com.framework_technology.esper.epl;

import com.framework_technology.esper.javabean.Apple;
import com.framework_technology.esper.javabean.Banana;
import com.java.annotation.document.Undigested;

/**
 * API - 5.15. Creating and Using Named Windows
 *
 * 创建 NamedWindow
 * 插入数据
 * 查询数据、按条件触发查询数据
 * 修改数据
 * 删除数据
 * 合并事件NamedWindow
 * 对NamedWindow建立索引
 *
 * @author wei.Li by 14-8-21.
 */
public class EPL_8_NamedWindow {

    /**
     * 创建 window  - ①在现有的数据类型上创建列
     * <p>
     * 语法:
     * [context context_name]
     * create window window_name.view_specifications
     * [as] [select list_of_properties from] event_type_or_windowname
     * [insert [where filter_expression]]
     * <p>
     * 1)context是关键字,后面跟着之前定义的context的名称。
     * 关于context的内容,{@link EPL_2_Context_1,EPL_2_Context_2,EPL_2_Context_3}
     * 2)create window后跟着要创建的named window的名字,且具有唯一性。名字后面紧跟着的“.”是用来连接事件过期策略的,即view。
     * 常用的view有win:length,win:length_batch,win:time,win:time_batch,std:unique,std:groupwin及自定义view等等,并且特定的view可以连用。
     * PS:view的相关内容{@link com.framework_technology.esper.views.View}
     * 3)select子句表示将某个事件定义中的全部或者某些属性作为named window所维护的事件属性。
     * 如果将某个事件的所有属性都加入到named window中,则可以通过select子句前的as连接事件名称,并且省略select子句。
     *
     * @return epl
     */
    protected static String createWindowExistingType() {
        String epl1 = "create window AppleWindow.win:keepall() as " + Apple.CLASSNAME;
        String epl2 = "create window AppleWindow.win:time(30 sec) as " +
                "  select id as appleId, price as applePrice from OrderEvent";
        return epl1;
    }

    /**
     * 创建 window  - ②自定义列的数据类型
     * <p>
     * 语法:
     * [context context_name]
     * create window window_name.view_specifications [as] (column_name column_type
     * [,column_name column_type [,...])
     *
     * @return epl
     */
    protected static String createWindowDefiningColumnsNamesAndTypes() {
        String epl1 = "create window SecurityEvent.win:time(30 sec) " +
                "(ipAddress string, userId String, numAttempts int, properties String[])";

        @Undigested(Description = "what is schema ?")
        String epl2 = "create schema SecurityData (name String, roles String[])";
        String epl3 = "create window SecurityEvent.win:time(30 sec) " +
                " (ipAddress string, userId String, secData SecurityData, historySecData SecurityData[])";

        return epl1;
    }


    /**
     * 创建 window  - ③将存在的 window 数据插入到新创建的 window 中
     * <p>
     * 语法:[context context_name] create window window_name.view_specifications as windowname insert [where filter_expression]
     * <p>
     * windowname后面紧跟insert,表示将该window中的事件插入到新建的named window中。where filter_expression表示过滤插入的事件。
     *
     * @return epl
     */
    protected static String populatingExistingNamedWindow() {

        String epl1 = "create window BananaEventWindow.win:time(10) as AppleEventWindow insert where price > 100";

        return epl1;
    }


    /**
     * 销毁 window
     */
    protected static void dropNamedWindow() {
        //EPStatement epStatement = epAdministrator.createEPL("epl . . .");
        //epStatement.destroy();
    }

    /**
     * 插入数据到 window
     * <p>
     * 语法:insert into window_name [(property_names)] [values (value_expressions) 或者查询方式 select value_expressions]
     * <p>
     * 查询 window 的数据,与普通查询相同
     *
     * @return epl[]
     */
    protected static String[] insertIntoDate() {

        String query_1 =
                "insert into OrdersWindow(orderId, symbol, price) values ('001', 'GE', 100)";
        //epService.getEPRuntime().executeQuery(query);

        String query_2 =
                "insert into OrdersWindow(orderId, symbol, price) select '001', 'GE', 100";
        //epService.getEPRuntime().executeQuery(query);

        //新建 window - 插入数据 - 查询数据
        String epl1 = "create window AppleWindow.win:keepall() as select id ,price from " + Apple.CLASSNAME;
        String epl2 = "insert into AppleWindow select id,price from " + Apple.CLASSNAME;
        String epl3 = "select * from AppleWindow(price>1) ";//查询方式与查询 javabean 方式相同

        return new String[]{epl1, epl2, epl3};
    }


    /**
     * 按照一定条件触发查询 window 的数据
     * <p>
     * 语法:
     * on event_type[(filter_criteria)] [as stream_name]
     * [insert into insert_into_def]
     * select select_list
     * from window_name [as stream_name]
     * [where criteria_expression]
     * [group by grouping_expression_list]
     * [having grouping_search_conditions]
     * [order by order_by_expression_list]
     *
     * @return EPL[]
     */
    protected static String[] triggeredOnSelect() {

        //新建 window - 插入数据
        String epl1 = "create window AppleWindow.win:keepall() as select id ,price from " + Apple.CLASSNAME;
        String epl2 = "insert into AppleWindow select id,price from " + Apple.CLASSNAME;

        //触发条件查询
        String epl3 = "on " + Banana.CLASSNAME + " as b select win.* from AppleWindow as win ";
        // "where b.id ='1' group by win.price having win.price >0 order by win.price";
        //将查询结果插入AppleWindow 中
        String epl4 = "on " + Banana.CLASSNAME + " as b insert into AppleWindow select * from AppleWindow as win ";
        // "where a.id ='1' group by win.price having win.price >1 order by win.price";

        return new String[]{epl1, epl2, epl3};
    }


    /**
     * 按照条件触发查询并删除 window 的数据
     * on trigger
     * select [and] delete select_list...
     * ... (please see on-select for insert into, from, group by, having, order by)...
     *
     * @return epl[]
     */
    protected static String[] triggeredOnSelectDelete() {

        //新建 window - 插入数据
        String epl1 = "create window AppleWindow.win:keepall() as select id ,price from " + Apple.CLASSNAME;
        String epl2 = "insert into AppleWindow select id,price from " + Apple.CLASSNAME;

        //触发条件查询
        String epl3 = "on " + Apple.CLASSNAME + " as a select and delete window(win.*)  from AppleWindow as win ";
        //"where a.id ='1' group by win.price having win.price >1 order by win.price";

        return new String[]{epl1, epl2, epl3};
    }


    /**
     * 更新 Update window 数据
     * <p>
     * on event_type[(filter_criteria)] [as stream_name]
     * update window_name [as stream_name]
     * set mutation_expression [, mutation_expression [,...]]
     * [where criteria_expression]
     *
     * @return epl[]
     */
    protected static String[] updateNamedWindow() {
        //simple example
        String epl1 = "on UpdateOrderEvent update AllOrdersNamedWindow set price = 0";
        String epl2 = "on ZeroVolumeEvent update AllOrdersNamedWindow set price = 0 where volume <= 0";

        //对于OrderUpdateEvent或者FlushOrderEvent事件进入后触发修改 win set 的条件用 if else 匹配
        String epl3 = "on pattern [every ord=OrderUpdateEvent(volume>0) or every flush=FlushOrderEvent] " +
                "update AllOrdersNamedWindow as win" +
                "set price = case when ord.price is null then flush.price else ord.price end" +
                "where ord.id = win.id or flush.id = win.id";


        String epl4 = "on UpdateEvent as upd" +
                "update MyWindow as win" +
                "set field_a = 1," +
                "field_b = win.field_a," + // 把 a修改后的值 1 赋给 b
                "field_c = initial.field_a ";// 把 a 更新前的值赋值给 c(关键字 initial)
        /**
         * 针对 epl4 :
         * update更新属性前会复制一份同样的事件暂存,比如initial这种操作就需要更新前的值,所以就需要我们实现序列化接口。
         * 如果不想通过代码完成这个序列化要求,也可以通过配置完成。
         * 另外还有以下几点需要注意:
         a)需要更新的属性一定要是可写的
         b)XML格式的事件不能通过此语句更新
         c)嵌套属性不支持更新
         */

        //Query 方式更新
        String query = "update AllOrdersNamedWindow set volume = 0 where volumne = 0";
        //epService.getEPRuntime().executeQuery(query);
        return new String[]{epl1, epl2};
    }


    /**
     * 删除 delete window 的数据
     * <p>
     * 语法:
     * on event_type[(filter_criteria)] [as stream_name] (Pattern 匹配->on pattern [pattern_expression] [as stream_name])
     * delete from window_name [as stream_name]
     * [where criteria_expression]
     *
     * @return epl[]
     */
    protected static String[] deleteNamedWindow() {

        //事件触发
        String epl1 = "on ZeroVolumeEvent delete from AllOrdersNamedWindow where volume <= 0";

        String epl2 = "on NewOrderEvent(volume>0) as myNewOrders" +
                "delete from AllOrdersNamedWindow as myNamedWindow " +
                "where myNamedWindow.symbol = myNewOrders.symbol";

        //Pattern 模式匹配
        String epl3 = "on pattern [every timer:interval(10 sec)] delete from MyNamedWindow";

        String epl4 = "on pattern [every ord=OrderEvent(volume>0) or every flush=FlushOrderEvent] " +
                "delete from OrderWindow as win" +
                "where ord.id = win.id or flush.id = win.id";

        //Query 方式删除
        String query = "delete from AllOrdersNamedWindow where volume <= 0";
        //epService.getEPRuntime().executeQuery(query);
        return new String[]{epl2, epl2};

    }

    /**
     * 合并事件
     * <p>
     *
     * @return epl[]
     */
    protected static String[] MergeWindow() {
    /*语法:
      on event_type[(filter_criteria)] [as stream_name]
      merge [into] window_name [as stream_name]
      [where criteria_expression]
       when [not] matched [and search_condition]
           then [
               insert [into streamname]
                   [ (property_name [, property_name] [,...]) ]
                   select select_expression [, select_expression[,...]]
                   [where filter_expression]
               |
               update set mutation_expression [, mutation_expression [,...]]
                   [where filter_expression]
               |
               delete
                   [where filter_expression]
           ]
           [then [insert|update|delete]] [,then ...]
       [when ...  then ... [...]]
     */

        /*
         a.第一行和前面的用法都一样。
         b.第二行的where语句将事件分为了matched(满足where条件)和not matched(不满足where条件)两类
         c.第三行的when配合matched或者not matched表示“window中满足where条件的事件,执行下面的操作/window中不满足where条件的事件,执行下面的操作”。
            search_condition为可选字段,表示再次过滤matched或not matched中的事件,只有没被过滤掉的事件才可以被then后面的语句操作。
         d.第四行的insert语句和之前说的insert into不太一样。
            虽然都表示插入事件,但是由于into streamname是可选,所以在只有insert关键字的情况下,会将触发的事件插入到当前的named window中。
            如果要指明插入到别的named window中就要在insert之后带上into及window的名字。
            再之后的圆括号中的内容表示要插入的事件的属性,一般情况是在将事件插入到别的window中时,用它来重命名第五行中列出的属性。
         e.第五行实际是配合第四行一起使用的。select子句不可少,不然引擎就不知道要往window中插入什么内容了。
            select的内容可以是*,也可以是属性列表。where语句再一次限制可插入的触发事件。注意select后面没有from,因为事件来源就是当时的触发事件。
         f.第七行用来更新符合条件的事件,可更新单个或多个属性,where条件判断是否可进行更新操作。
         g.第九行用来删除符合条件的事件,只包含关键字delete以及可选的where语句。
         h.最后两行表示on merge中可以有多个when,每个when可以有多个then及insert或updata或delete语句,这样就能组成一个非常复杂的merge操作了。
         */
        //在下面的例子中每一个匹配子句包含两个动作,一个动作中插入一个日志事件和第二动作插入、删除或更新
        String epl1 = "on OrderEvent oe" +
                "  merge OrderWindow pw" +
                "  where pw.orderId = oe.orderId" +
                "  when not matched " +
                "    then insert into LogEvent select 'this is an insert example' as name" +
                "    then insert select *" +
                "  when matched and oe.deletedFlag=true" +
                "    then insert into LogEvent select 'this is a delete example' as name" +
                "    then delete" +
                "  when matched" +
                "    then insert into LogEvent select 'this is a update example' as name" +
                "    then update set pw.quantity = oe.quantity, pw.price = oe.price";

        //根据条件判断,进行2此修改
        String epl2 = "on OrderEvent oe" +
                "  merge OrderWindow pw" +
                "  where pw.orderId = oe.orderId" +
                "  when matched" +
                "    then update set clearorder(pw) where oe.price < 0" +
                "    then update set pw.quantity = oe.quantity, pw.price = oe.price where oe.price >= 0";
        return new String[]{epl1, epl2};
    }


    /**
     * 对named window中存放的事件的属性建立索引
     * <p>
     * 语法:
     * create [unique] index index_name on named_window_name (property [hash| btree] [, property] [hash|btree] [,...] )
     * <p>
     * unique代表建立唯一索引,如果插入了重复的行,则会抛出异常并阻止重复行插入。
     * 如果不使用此关键字,则表示可以插入重复行。
     * index_name为索引的名称,named_window_name是要建立索引的named window。
     * 后面的括号中包含named window中的属性以及索引类型。
     * 索引类型分两种,hash索引不会排序,如果有=操作,建议使用此类型索引。
     * btree索引基于排序二叉树,适合<, >, >=, <=, between, in等操作。
     * 如果不显式声明hash或者btree,则默认为hash索引。
     *
     * @return epl[]
     */
    protected static String[] IndexingNamedWindows() {
        String epl1 = "create unique index UserProfileIndex on UserProfileWindow(userId, profileId) ";
        String epl2 = "create index idx1 on TickEventWindow(symbol hash, buyPrice btree)  ";
        return new String[]{epl1, epl2};
    }
}


转载于:https://my.oschina.net/huluerwa/blog/311312

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值