深入浅出事件流处理NEsper(二)

NEsper使用的事件类型来描述事件的类型信息。你的应用在启动时可能预先配置定义事件类型,或者在运行时通过API或EPL语法动态的增加事件类型。

EPL中的create schema 的语法允许在运行时用EPL申明一个事件类型。

2.1事件对象

事件是过去发生的动作或状态变化的一个不可改变的记录。事件属性捕捉事件的状态信息。

在ESPER中,事件是可以被描述成以下任何一种CLR对象:

NEsper为声明一个事件提供了多种的选择,没有绝对的需要用户去创建一个CLR对象来代表一个事件。事件表达有以下共性:

• 所有的事件表示支持嵌套,索引和映射属性(亦称属性表达),在下面详细解释前。嵌套级别没有限制。

• 所有的事件表示提供事件类型元数据。这包括嵌套属性的类型元数据。

• 所有事件表示允许调换事件本身和部分属性图到新的事件。条件调换是指选择那些本身是嵌套的属性图的事件本身或事件属性,然后查询事件的性质或嵌套属性图。Apache的Axiom事件表示是一个例外,目前不允许调换的事件属性,但允许调换的事件本身。

• CLR对象和Map描述允许超类型。

所有事件表示的API的行为是相同的,在这一章中指出的少数例外。多个事件陈述的好处有:

• 对于已经支持的陈述事件的应用程序,没有必要作事件到CLR对象的转换处理。

• 事件陈述是交互的,当事件陈述发生改变时,需要减少或消除变更声明。

• 事件陈述是可共同使用的,允许所有的事件表示在相同或不同报表中的共同使用。

• 选择使得其可能自觉地权衡性能,易于使用。

2.2事件属性

事件属性捕捉事件的状态信息。事件属性的简单的索引,映射和嵌套的事件属性。下表列出了不同类型的属性和它们的语法在事件表达中。该语法允许语句来查询深CLR 对象图,XML结构和MAP事件。 如下图:

合并也有可能。例如,一个有效的组合,可以的Person.Address("home”).street[0]。

2.2.1转义字符

如果你的应用程序使用System.Collection.Generic.IDictionary或者XML描述事件,事件属性名称会包括一个点号(“.”)字符。反斜杠(“\”)可以用来转换点号,允许事件名称中包括点号。

select part1\.part2 from MyEvent

有时,你的事件属性可能会重叠EPL语言关键字。在这种情况下,你可以使用向后撇号'字符转义属性的名称。

下例假定一个Quote事件,有一个order的属性,而order也是一个保留关键字:

select `order` from Quote

2.3动态属性

动态(未选中)属性是不需要在语句的编译时知道的事件属性。这些属性是在运行过程中解析。

动态属性背后的想法是,对于一个给定的潜在事件,我们并不总是事先知道的所有属性。一个潜在的事件可能在语句的编译时不附加属性,而我们要查询。尤其是丰富的,面向对象的域模型的事件表示非常有用的概念。

动态属性的语法包含属性的名称和一个问号。索引,映射和嵌套的属性也可以动态特性。

动态属性总是返回System.Object的类型。此外,如果在运行时动态属性不存在,动态属性返回一个空值。

例如,考虑一个OrderEvent事件提供了一个“item”属性。 “item”属性是类型对象且持有服务或产品的一个实例的引用。

假设服务和产品类提供了一个名为“price”的属性。通过一个动态的属性,我们可以指定一个查询,以获得从任一对象​​(服务或产品)的price属性:

select item.price? from OrderEvent

另一个例子,假设Server类包含一个serviceName属性,而Product类不拥有,下面的查询返回Server对象的serviceName属性。对于没有serviceName属性的Product对象,将返回一个空值:

select item.serviceName? from OrderEvent

考虑OrderEvent有多个实现类,其中有一些timestamp属性的情况。下一个查询返回的这些实现OrderEvent接口功能的实例的timestamp属性:

select timestamp? from OrderEvent

上面的查询返回类型事件的单个列名timestamp?

当为嵌套的动态属性,动态属性的所有属性也考虑动态特性。在下面的例子中的查询要求direction属性对象返回的detail的动态属性:

select detail?.direction from OrderEvent

上面的EPL等同于如下:

select detail?.direction? from OrderEvent

与动态属性协同提供的有用的函数如下:

• CAST函数动态属性(或表达式的值)转换成给定的类型。

• exists函数检查是否存在一个动态的属性。如果事件有该名称的属性,返回true,否则返回false。

• instanceof函数检查动态属性的值(或表达式的值)是否是任何给定的类型。

• typeof函数返回字符串类型的动态属性名称。

动态事件属性与所有CLR对象,基于Map和XML基于DOM的事件一起工作。

2.4 Fragment and Fragment 类型

有时一个事件的属性能是事件本身。ESPER使用条款碎片和碎片类型来表示这种事件。最好的例子是一个模式相匹配的两个或两个以上的事件且输出事件包含匹配的事件作为片段。换句话说,输出事件由更多的事件,碎片组成的复合事件。

片断具有相同的元数据作为其封装的复合事件。封装的复合事件的元数据包含属性是片段的信息,或有一个属性值能代表片断或者事件本身。

片段和类型的元数据,可以让您的应用程序导航的复合事件,而不需要使用CLR反射API和减少耦合底层的事件表示。

2.5普通的原CLR对象事件

普通的旧式CLR对象的事件是通过CLR 风格的getter方法​​,暴露事件属性的对象实例。事件类或接口不完全符合CLR 规范的;但是Esper引擎来获取事件属性,所需的Get属性,​必须是当前的或一个可以通过配置中定义的访问器方法。

NEsper支持CLR 风格的事件类扩展的超类或实现一个或多个接口。此外,NEsper事件模式和EPL申明可以参考CLR 接口类和抽象类。

代表事件的类应是一成不变的。由于事件是记录状态改变或过去发生的行动,有关事件属性不应该改变的。然而,这是不是一个硬性的要求,NEsper引擎接受事件还是可变的。

没有必要实现GetHashCode和Equals方法。这些方法的实施是CLR事件类,不影响引擎的任何方式的行为。

2.5.1 CLR对象事件

如前所述,不同的属性类型都支持标准的CLR规范,且有些具有NEsper的独特支持:

• Simple- 属性可以检索单个值。相关的属性类型可能是原始CLR 语言(如INT,一个简单的对象(如System.String),或更复杂的对象,复杂对象是由CLR语言的应用程序定的,或一个类库包含的应用程序。

• Indexed -索引属性存储,可以单独由一个整数值,非负指数(或下标)来访问的对象(同一类型的所有)的有序集合。

• Mapped -NEsper接受字符键值对映射属性的任何属性。

• Nested -嵌套属性是一个属性所属的CLR对象本身就是另一个事件的属性。

如下图所示,假设有NewEmployeeEvent事件类。在这个例子中返回CLR对象的映射和索引属性,但也可能返回CLR 语言中的原始类型(如int或String)。Address对象和Employee有嵌套属性,如Address对象的街道名称或Employee对象的雇员名称。

public class NewEmployeeEvent {
      public String FirstName { get; }
      public Address GetAddress(String type);
      public Employee GetSubordinate(int index);
      public Employee[] AllSubordinates { get; }
}

Simple事件属性需要返回属性值的getter属性。在这个例子中,FirstName 属性​​返回String型的firstName属性。

Indexed事件属性要求任何一个以下的getter方法。一是采用一个整数类型作key值,并返回该属性的值的方法,如GetSubordinate,或一个返回数组类型,或实现迭代的类的方法。例如getSubordinates 方法,返回一个Employee 数组,但也可能返回一个可迭代的。 EPL或事件模式的语句,索引属性通过[index]语法访问。

Mapped事件属性需要一个getter方法,该方法通过键值对并返回该属性的值,如GetAddress方法。 EPL或事件模式声明,映射属性通过属性(“key”)语法访问。

Nested事件属性需要一个getter方法返回嵌套对象。 GetAddress和 GetSubordinate方法映射和索引返回一个嵌套对象的属性。 EPL或事件模式声明,嵌套的属性是通过property.nestedProperty语法访问。.

所有事件的模式和EPL表达式允许使用索引,映射和嵌套属性(或这些的联合)。下面的例子显示事件模式表达式的过滤器(每行是一个单独的EPL表达式)的索引,映射和嵌套属性的不同组合:

every NewEmployeeEvent(firstName='myName')

every NewEmployeeEvent(address('home').streetName=' Park Avenue')

every NewEmployeeEvent(subordinate[0].name='anotherName')

every NewEmployeeEvent(allSubordinates[1].name='thatName')

every NewEmployeeEvent(subordinate[0].address('home').streetName='Water Street')

同样,语法可用于在EPL表达式在所有可以预测的事件属性名称的情况下,如在select列表,where条件或加入标准。

select firstName, address('work'), subordinate[0].name, subordinate[1].name from NewEmployeeEvent where address('work').streetName = 'Park Ave'

2.5.2属性名称

NEsper配置提供了一个关闭区分大小写的属性名称的标志。下图是getter方法​​和属性名称的示例列表:

2.5.3常量和枚举

常量是在CLR 类中用public static const声明的成员,也可参与各种表现形式,如这个例子所示:

select * from MyEvent where property=MyConstantClass.FIELD_VALUE

事件属性是枚举值可以比较他们的枚举值:

select * from MyEvent where enumProp=EnumClass.ENUM_VALUE_1

另外,类中可以声名静态的方法,如枚举类EnumClass如下:

select * from MyEvent where enumProp=EnumClass.valueOf('ENUM_VALUE_1')

如果您的应用程序不引入,通过配置枚举类的包,它必须指定类的包名。枚举类是内部类必须遵守CLR约定使用"+"。

例如:枚举类Color是MyEvent的内部类,在org.myorg包中可以引用如下所示:

select * from MyEvent(enumProp=org.myorg.MyEvent+Color.GREEN).std:firstevent()

实例方法也可能被调用事件实例指定一个流名称,如下所示:

select myevent.computeSomething() as result from MyEvent as myevent

链接的实例方法是支持的,如这个例子说明:

select myevent.GetComputerFor('books', 'movies').Calculate() as result from MyEvent as myevent

2.5.4参数化的类型

当你的getter方法​​或访问器成员返回一个类型,例如索引属性IEnumerable或者映射属性IDictionary,于是属性表达式可能通过参数类型引用属性

一个参数化类型的事件的属性例子是:

public class NewEmployeeEvent {
public String Name { get; }
public IEnumerable Education { get; }
public IDictionary Addresses { get; }
}

此事件的有效属性表达式的示例如下所示:

select Name, Education, Education[0].Date, Addresses('home').Street from NewEmployeeEvent

2.6.1概述

事件也可以被实现了System.Collection.IDictionary 接口的对象代表。Map事件的属性是map值,通过了System.Collection.IDictionary接口暴露的get方法访问。

Map事件类型是一个综合型的系统,它可以消除需要使用CLR类的事件类型,从而更容易在运行时改变的类型或从其他来源产生的类型信息.

一个给定的Map事件类型可以有一个或多个也是map类型的超类,它可用到在任何Map超类型上可用的所有属性类型。此外,在EPL内的任何地方,使用一个map超类的事件类型名称,任何map子型及它们的子型都匹配表达式。

你的应用程序在运行时通过配置操作UpdateMapEventType,可以添加属性到现有的Map事件类型中。map属性不会被更新或删除 ,只能添加属性,嵌套的属性也可以添加。运行时配置也允许删除map事件类型和添加新的类型的信息。

在您的应用程序配置map事件类型通过提供一个类型名称,类型名称可用于进一步的map事件类型定义,去指定属性类型或一个数组属性类型的类型名称。

一对多关系在Map事件类型中是通过数组表示,一个在Map事件类型中的属性可能是一个简单的数组,一个CLR 对象组或是一个map组。

引擎在EPRuntime接口中通过SendEvent(DataMap map, String eventTypeName)方法来执行Map事件。实例在map中表现为事件属性。Key值必须是字符串,引擎才能找到Pattern或者EPL指定的事件属性名。

引擎不会验证事件类型名称或值。你的应用程序应确保通过的对象作为事件属性匹配create schema 属性名和类型,或者在运行时配置事件类型信息或静态配置。

2.6.2 MAP属性

Map事件属性可以是任何类型。Map属性是CLR应用程序提供对象:

• 如前所述,属性是CLR应用程序对象可以通过嵌套,索引,映射和动态属性的语法查询。

• Map类型的属性可以嵌套任意深度,因此可以被用来表示复杂的域信息。嵌套,索引,映射和动态属性的语法,可以用来在Map或数组内查询。

为了使用Map事件,事件类型名称和属性名称和类型必须通过配置让引擎知道。请参见13.4.2节的例子,“System.Collection.Generic.IDictionary的代表事件”。

下面的代码片断创建和处理Map事件。它首先定义了一个CarLocationUpdateEvent事件类型:

var mapEvent = new Dictionary<string,object>();
mapEvent["carId"] = carId;
mapEvent["direction"] = direction;
epRuntime.SendEvent(mapEvent, "CarLocUpdateEvent");

CarLocUpdateEvent现在能用在EPL表达式中

select carId from CarLocUpdateEvent.win:time(1 min) where direction = 1

该引擎还可以通过嵌套属性的语法,查询CLR 对象在Map事件中的值。因此,Map事件,可用于聚合多个数据结构到一个简单事件,时行方便的综合信息查询。下面的例子演示Map事件与account 对象。

var mapEvent = new Dictionary<string,object>();
mapEvent["txn"] = txn;
mapEvent["account"] = account;
epRuntime.SendEvent(mapEvent, "TxnEvent");

2.6.3 MAP父类

你的Map事件类型可以声明一个或多个超类型,在引擎初始化时或运行时,通过管理界面配置。

Map事件类型的超类,也必须是Map事件类型。父类所有属性名称和类型也可在子类中重载。此外,在EPL中,一个Map超类的事件类型名称用被应用,任何子类表达式也相匹配(类似于CLR 接口的概念)。

这个例子假定BaseUpdate事件类型已经声明,且作为一个AccountUpdate事件类型的超类(两个都是Map事件类型):

epService.EPAdministrator.GetConfiguration().
AddEventType("AccountUpdate", accountUpdateDef,new String[] {"BaseUpdate"});

你的应用程序EPL表达式中可能会选择BaseUpdate事件,会收到BaseUpdate和

AccountUpdate事件,以及BaseUpdate的任何其它子类。

select * from BaseUpdate

你的应用程序Map事件类型可能有多个超类。多重继承层次结构之间的MAP可以任意深度,但是循环依赖是不允许的。如果使用运行时配置,增加子类时,必须父类先存在。

2.6.4 MAP高级属性类型

嵌套属性:

强壮的类型嵌套的map事件可以被用来建立丰富,类型安全的事件类型。使用AddEventType方法配置在初始化时或运行时定义的类型。值得注意的地方:

• CLR 的对象(POCO),可以作为属性出现在MAP嵌套中。

• 一个Map中便用的事件类型名称可能代表一个Map嵌套,或者Map嵌套数组.

• 嵌套的级别没有限制

• 动态属性,可以用来查询Map内可能无法预先知道的key.

• 在嵌套结构的访问路径后面不能映射不存在的实体,该引擎返回的属性为null。

一对多关系:

对在map内模型重复的属性,你可以使用Map的属性数组。你可以使用原始类型的数组或CLR 对象的数组或一个先前定义的Map事件类型的数组.

当使用先前宣布的Map事件类型作为一个数组属性,literal[]必须追加在事件类型名称后。.

下面的例子定义了一个名称Sale的Map事件类型,拥有各类型的数组属性。它假定SalesPerson 的CLR 类存在和OrderItem的被声明为一个Map事件类型:

Map<String, Object> sale = new HashMap<String, Object>();
sale["userids"] = typeof(int[]);
sale["salesPersons"] = typeof(SalesPerson[]);
sale["items"] = "OrderItem[]"; // The property type is the name itself appended by []
epService.EPAdministrator.GetConfiguration().
AddEventType("SaleEvent", sale);

上面的例子中声明的三种属性:

• 整数类型数组userid

• 对象数组 SalesPerson

• Map类型数组 orderitems.

下来的EPL声明对数组属性值查询的示例:

select userids[0], salesPersons[1].name,items[1], items[1].price.amount from SaleEvent

本文来自合作伙伴“doNET跨平台”,了解相关信息可以关注“opendotnet”微信公众号

时间: 2024-10-03 18:51:15

深入浅出事件流处理NEsper(二)的相关文章

深入浅出事件流处理NEsper(一)

对实时信息分析和处理,常常需要客户应用程序的开发相应功能.一般地,这些功能需要提供以下的处理流程,分析获取的数据,筛选数据,提取出有用的信息,然后将其通过特定的形式展现出来.由于具体实时信息的高并发性和高吞吐量的需求,这就需要客户应用程序具有高度扩展性和响应能力,而在数据处理领域.NEsper就是一个.NET 开源的针对此类问题的事件流处理解决方案,其目的在于简化有此需求的客户应用程序的开发. 1.1.CEP与事件流 NEsper 的目的在于为应用程序提供分析和响应事件的要求.典型的应用需求如下

深入浅出事件流处理NEsper(三)

首先介绍一下NESPER的大体结构,NEsper从内容上分为两块,NEsper的核心NEsper.dll和NEsper.IO.dll. (1)NEsper的核心包包含了EPL语法解析引擎,事件监听机制,事件处理等核心模块. (2)NEsper的io包含从各种数据源读取数据以及将输出结果写入各种数据源,包括excel,database,msmq,http,socket,XML. 贴一张esper官网上的结构图,方便大家了解esper的结构 nesper 接下来对上述结构图进行详细的解释让大家加深对

Smooks结构化事件流处理

概览 Smooks是一个开源的Java框架,用于处理"数据事件流".它常常被认为是一个转换框架并以此被用于好几个产品和项目中,包括JBoss ESB(以及其它ESB).然而究其核心,Smooks未提及"转换"或者其它相关的词汇.它的应用远不只这一点! Smooks的工作是将结构化/层次化的数据流转变成"事件"流,然后交与"访问者逻辑(Visitor Logic)"进行分析,生成结果(可选的). 源 ->结构化事件流(访问

JavaScript事件学习小结(一)事件流_javascript技巧

相关阅读: JavaScript事件学习小结(五)js中事件类型之鼠标事件 http://www.jb51.net/article/86259.htm JavaScript事件学习小结(一)事件流 http://www.jb51.net/article/86261.htm javaScript事件学习小结(四)event的公共成员(属性和方法) http://www.jb51.net/article/86262.htm JavaScript事件学习小结(二)js事件处理程序 http://www

学习JavaScript事件流和事件处理程序_javascript技巧

本文全篇介绍了JavaScript事件流和事件处理程序,分享给大家供大家参考,具体内容如下 一.事件流 事件流描述的是从页面中接收事件的顺序.IE的事件流是事件冒泡流,而Netscape Communicator的事件流是事件捕获流. 二.事件冒泡 即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点.如: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT

DOM 事件流详解

 这篇文章主要详细介绍了DOM中的事件流,包括冒泡型事件.事件监听.标准DOM事件监听这三个方面,十分详细,推荐给大家.     1.冒泡型事件 浏览器的事件模型分两种:捕获型事件和冒泡型事件.由于ie不支持捕获型事件,所以以下主要以冒泡型事件作为讲解. (dubbed bubbling)冒泡型指事件安装最特定的事件到最不特定的事件逐一触发.   代码如下: <body onclick="add('body<br>')"> <div onclick=&qu

Silverlight+WCF 新手实例 象棋 主界面-事件区-游戏开始(二十七)

本专题出产简单原由: 一开始的初衷,只是想写个简单的单机BS人机对战版的,开始还下了点AI算法看看的: 但是写到最后,都写成了通讯版本的对战了,只因中间不小心看到了WCF的相关内容,顺便加了进来; 最后就定局了,反正新手实例,能加多点内容就加多点了. 关于原始初衷,后期再补上了.       好了,先上几个附加索引: 1:Silverlight+WCF 新手实例 象棋 在线演示 2:Silverlight+WCF 简单部署问题集 3:Silverlight4 ListBox bug 4:Silv

《C#并发编程经典实例》—— 用限流和抽样抑制事件流

声明:本文是<C#并发编程经典实例>的样章,感谢图灵授权并发编程网站发布样章,禁止以任何形式转载此文. 问题 有时事件来得太快,这是编写响应式代码时经常碰到的问题.一个速度太快的事件流可导 致程序的处理过程崩溃. 解决方案 Rx 专门提供了几个操作符,用来对付大量涌现的事件数据.Throttle 和 Sample 这两个操 作符提供了两种不同方法来抑制快速涌来的输入事件. Throttle 建立了一个超时窗口,超时期限可以设置.当一个事件到达时,它就重新开始计 时.当超时期限到达时,它就把窗口

javascript下对于事件、事件流、事件触发的顺序随便说说_javascript技巧

1.首先我们来了解几个概念,"事件","事件流","事件名称","事件处理函数/事件监听函数,也许是"老生常谈",知道的朋友可以越过. 事件: 事件是用户自身或浏览器进行的特定行为.如:用户点击 也就是常用的click事件 事件流:多个事件 按一定顺序触发 形成了事件流 事件名称:如上面所讲的click就是事件名 事件处理函数/事件监听函数(Dom的叫法)就是 事件触发后的处理函数,如obj.onclick=fn;函