天天看點

程式員的量化交易之路(3)--Esper事件Event(2)第二章 EventPresentation 事件描述

這一章用于說明事件描述和模組化的方法。

esper 使用event type(事件類型)來描述事件的類型資訊。

你的應用可以在esper啟動時或者在運作時通過api或者epl文法來添加事件類型。具體參見16.4節“條目配置”,關于啟動時配置,15.3.8“運作時配置”,關于運作時配置api。

epl的create schema文法允許在運作時聲明一個事件類型,具體參見5.15節“聲明一個事件類型:createschema”

在15.6節“事件及事件類型”,我們将會解釋事件類型如和對epl語句可見以及輸出由引擎傳遞的事件。

事件是一個不變的記錄,它記錄了過去發生的動作或者狀态的改變。事件的屬性(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說明了不同類型的屬性以及他們在事件表達式中的文法,這種文法支援對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]。

此外,索引和映射括号内還支援表達式,下面我們會有例子說到。

如果你的應用又使用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

鍵或索引表達式必須放置在括号内。當使用一個表達式作為映射屬性的關鍵字時,該表達式必須是一個代表字元串類型的表達式。當使用一個表達式作為索引屬性的索引時,該表達式必須代表的是一個整形。

假設一個類聲明了這些屬性(為了簡略,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)

動态屬性(無需檢查)是一種在語句編譯時無需确定的事件屬性,這種屬性在運作時解決,他們提供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用于傳回動态屬性的類型的類型名稱。

這一篇就暫時到這裡,下一篇繼續說明第二章事件的内容。