且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

程序员的量化交易之路(3)--Esper事件Event(2)

更新时间:2021-12-13 21:21:48

第二章 EventPresentation 事件描述

欢迎转载学习,但转载须注明出处:http://blog.csdn.net/minimicall,尊重劳动成果,版权归我。

这一章用于说明事件描述和建模的方法。

 

Esper 使用event type(事件类型)来描述事件的类型信息。

你的应用可以在Esper启动时或者在运行时通过API或者EPL语法来添加事件类型。具体参见16.4节“条目配置”,关于启动时配置,15.3.8“运行时配置”,关于运行时配置API。

EPL的create schema语法允许在运行时声明一个事件类型,具体参见5.15节“声明一个事件类型:createschema”

在15.6节“事件及事件类型”,我们将会解释事件类型如和对EPL语句可见以及输出由引擎传递的事件。

2.1 事件底层Java对象

事件是一个不变的记录,它记录了过去发生的动作或者状态的改变。事件的属性(Properties)记录了事件的状态信息。

在Esper中,一个事件可以由表2.1中的Java对象表示。

表2.1 事件的底层Java对象

Java类

描述

Java.lang.Object

任何遵循JavaBean约定并带有getter方法的Java POJO(plain-old java object)对象;遗留的Java类即便没有尊徐JavaBean约定也可以当做事件

Java.util.Map

Map事件是由java.util.Map接口实现的,其中每个map条目就是属性值

Object[](对象数组)

对象数组事件是一组对象的数组,数组中每个元素就是属性值

Org.w3c.dom.Node

XML 文档对象模型(DOM)

Org.pache.axiom.om.OMDocument 或OMElement

XML流

Application classes

Plug-in事件由扩展API描述

 

Esper提供了描述事件的多种手段。你并不是非得去新建一个类来描述一个事件。

Esper事件的描述具有以下共性:

1)  所有事件描述支持复合嵌套(nested)、下标(indexed)和映射(mapped)属性,并且嵌套层次不限。

2)  所有事件描述方式都提供了事件类型的元数据,包括嵌套属性的类型元数据。

3)  所有事件描述方式都支持事件置换。所谓事件置换指的是事件或者事件属性可以在将来的语句中进行查询(什么鬼,我是不懂这句话是什么意思,求解)

All eventrepresentations allow transposing the event itself and parts of all of itsproperty graph into new events. The term transposing refers to selecting theevent itself or event properties that are themselves nestable property graphs,and then querying the event's properties or nested property graphs in furtherstatements. The Apache Axiom event representation is an exception and does notcurrently allow transposing event properties but does allow transposing theevent itself

4)  Java对象、映射和数组对象表示方法允许基类存在。

所有事件表现的API行为都一致,有些小的例外我们将会在本章标出。

多种事件描述方式的好处有:

1)  对于那些已经存在一些事件,而这些事件是上述支持的事件的一种或多种,那么就没有必要对事件进行转换。

2)  事件的描述是可交换的,这减少了事件状态的改变,当事件描述方式改变时。

3)  事件描述是可互操作的,允许事件在单条或多条语句间相互操作。

4)  多种事件描述还可以实现对交易的性能感知、易用、演化、导入和导出事件等。

 

2.2 事件属性

事件属性保存了事件的状态信息。事件属性可以很简单,也可以是下标、映射和嵌套事件属性。表2.2说明了不同类型的属性以及他们在事件表达式中的语法,这种语法支持对JavaBean、XML结构化对象、Map事件等的深度查询。

表2.2 事件属性的类型

类型

描述

语法

示例

Simple(简单)

一个简单的属性值

name

sensorId

Indexed(索引/下标)

一个索引属性存储的是一组同类型的顺序对象,通过下标可以单独获取

Name[index]

sensor[0]

Mapped(映射)

映射属性通过关键字来映射存储

Name(‘key’)

sensor(‘light’)

Neted(复合嵌套)

嵌套属性是属性又是另一个对象(事件)

name.nestedname

sensor.value

 

上述几种类型的复合也是可以的,例如person.address(‘home’).street[0]。

此外,索引和映射括号内还支持表达式,下面我们会有例子说到。

 

2.2.1 转义字符(Escape Characters)

如果你的应用又使用java.util.Map,Object[]或者XML来表达事件,这些事件属性名称中就含有点”.”符号。这个时候,你需要使用反斜杠“\”来进行转义。

例如在如下EPL表达式中,属性part1.part2,:

Select part1\.part2 from MyEvent

 

有时候你的EPL表达式包含了空格或者EPL语言的关键字或者其它特殊字符,这个时候你需要使用`(反引号,tab键上面,1键左边那个)去转义。

 

例如下面这个例子,Quote事件存在一个属性名为order,但order是EPL的保留字,所以需要转义:

select `order`, price as `price.for.goods`from Quote

 

当要转义映射或索引属性时,需要保证反引号出现在map key或 index的外面(outside)

 

下面这个例子是事件属性名中含有空格以及含有特殊符号’(例如 children’sbooks):

select `candidate book` , `children'sbooks`[0], `book select`('isbn') from MyEventType

 

 

2.2.2 表达式作为映射关键字或者数组的下标

键或索引表达式必须放置在括号内。当使用一个表达式作为映射属性的关键字时,该表达式必须是一个代表字符串类型的表达式。当使用一个表达式作为索引属性的索引时,该表达式必须代表的是一个整形。

 

假设一个类声明了这些属性(为了简略,getter方法被简略掉了):

 

public class MyEventType {

 String myMapKey;

  intmyIndexValue;

  intmyInnerIndexValue;

 Map<String, InnerType> innerTypesMap; // mapped property

 InnerType[] innerTypesArray; // indexed property

}

 

public class InnerType {

 String name;

 int[] ids;

}

下面是一个展示表达式作为映射key和索引的EPL语句:

 

select innerTypesMap('somekey'),  // returns map value for 'somekey'

 innerTypesMap(myMapKey),        //returns map value for myMapKey value (an expression)

 innerTypesArray[1],             //returns array value at index 1

 innerTypesArray(myIndexValue)   //returns array value at index myIndexValue (an expression)

 from MyEventType

 

可以通过点操作来访问事件属性的属性(数据成员),下面是一个示例:

 

select innerTypesMap('somekey').ids[1],

 innerTypesMap(myMapKey).getIds(myIndexValue),

 innerTypesArray[1].ids[2],

 innerTypesArray(myIndexValue).getIds(myInnerIndexValue)

 from MyEventType

 

2.3 动态事件属性

动态属性(无需检查)是一种在语句编译时无需确定的事件属性,这种属性在运行时解决,他们提供duck typing 功能。

动态属性所面对的是,对于一个潜在的事件,我们并不是总能够事先知道它的所有属性。这个事件可能存在一些在编译时我们不知道的属性,但我们又会在后面查询用到。这种概念在事件描述那些丰富的、面相对象模型的时候非常有用。

动态属性的语法是属性名加疑问号?,索引、映射和嵌套属性都可以是动态属性。

表2.3 事件属性的动态类型

类型

语法

Dynamic Simple

name?

Dynamic Indexed

name[index]?

Dynamic Mapped

name(‘key’)?

Dynamic Nested

name?nestedPropertyName

 

动态类型总是返回java.lang.Object类型。如果事件没有该动态属性,那么就会返回null。

举个例子,假如一个OrderEvent事件,它有一个“item”属性,这个“item”属性是一个对象,可能指向Service,也可能指向Product。

我们假设Service和Product类都有属性“price”。通过动态属性,我们可以获得一个价格属性,而无论它指向的是哪个对象(Service或Product):

 

select item.price? from OrderEvent

 

接下来,我们假设Service类包含一个“serviceName”属性,而Product类并没有该属性。那么下面的查询语句则会根据指向的对象返回不同的结果:

 

select item.serviceName? from OrderEvent

 

当item指向的是Service类的对象实例时,返回一个存在的值,当指向的是Product类的对象实例时,返回null。

 

我们假设OrderEvent是一个基类,它有一个名为timestamp的属性,并且OrderEvent有很多派生类来实现它。那么下面语句可以返回timestamp的值,不管查询对象指向的是OrderEvent的哪个派生类的实例:

 

select timestamp? from OrderEvent

 

假如动态属性是嵌套的,那么这个动态属性内部的所有属性也是动态的。下面示例中查询“direction”属性,它是动态属性“detail”的属性:

 

select detail?.direction from OrderEvent

 

上面语句等价于:

 

select detail?.direction? from OrderEvent

 

下面的函数配合动态属性非常有用:

1)  cast函数将动态属性裁剪为指定类型。

2)  exists函数用于检查事件事件是否存在该动态属性。

3)  instanceof用于检测动态属性是否为给定类型

4)  typeof用于返回动态属性的类型的类型名称。


这一篇就暂时到这里,下一篇继续说明第二章事件的内容。