天天看点

程序员的量化交易之路(5)--Esper之Map事件(4)

实现事件的类可以是一个实现java.util.map接口的类。映射事件的事件属性是其通过get方法能够获得的值。

和数组对象事件类型一样,映射事件类型考虑了系统中的综合类型,是的不需要使用java类来描述事件类型,这是的更容易在运行时更改事件,或者从其他类型生成类型信息。

一个给定的map事件类型可以有一个或者多个超类型,这些超类型也必须是map 事件类型。所以在超类中可以获取的属性在该映射事件中也可以获得。此外,在epl中任何一个map超类被使用,那么其子类都可以匹配该表达式。

应用可以通过configurationoperation(配置操作)updatemapeventtype在运行时为一个已经存在的映射事件类型添加属性。属性只能增加,不能更新或者删除。运行时配置允许删除一个映射事件类型并修改后再添加回系统中。

通过数组可以在映射事件类型中表示一对多的关系。映射事件类型中的一个属性可以是一个内置类型的数组,java对象的数组,map的数组以及数组的数组,都是可以的。

引擎通过epruntime接口中的sendevent(map map,string eventtypename)方法处理java.util.map事件。映射中的条目代表这属性。关键字必须是java.util.string类型,为了使引擎能够通过匹配名字取查找事件属性。

引擎并不验证映射事件属性名和值。应用必须保证事件属性匹配create schema属性名和类型。

映射事件属性可以是任意类型。它可以是java应用对象、java.util.map类型、object[]数组类型等。这些复杂的类型可以提供一下更强的功能:

1)  使用java application object的属性可以嵌套、索引、映射以及使用动态属性等。

2)  使用map作为事件属性可以表达更为复杂的事件,并且该属性可以被嵌套、索引、动态属性等。

3)  使用数组对象作为事件属性也是如此。。。。

为了使用映射事件类型,事件类型名称和属性名以及属性类型等必须让引擎知道,可以通过configuration或者create schema epl语法实现。具体例子参见5.15节“declaring aneventtype:create schema”和第16.4.2节“eventsrepresed by java.util.map”

下面的代码定义了一个映射事件类型,穿件一个映射事件并将该事件发送到引擎中。示例中通过运行时配置接口(create schema 和静态配置也可以)。

// define carlocupdateevent event type(example for runtime-configuration interface)

map<string, object> def = newhashmap<string, object>;

def.put("carid", string.class);

def.put("direction", int.class);

epservice.getepadministrator().getconfiguration().

 addeventtype("carlocupdateevent", def);

carlocupdateevent事件类型可以在如下语句中使用:

select carid fromcarlocupdateevent.win:time(1 min) where direction = 1

创建一个carlocupdateevent事件并将它发送到引擎中:

// create a carlocupdateevent event andsend it into the engine for processing

map<string, object> event = newhashmap<string, object>();

event.put("carid", carid);

event.put("direction",direction);

epruntime.sendevent(event,"carlocupdateevent");

通过嵌套属性,引擎允许把一个对象当做映射事件中的属性值来查询。这样map就可以用来聚合多个数据结构到单个事件中。下面是这样的一个例子。

map event = new hashmap();

event.put("txn", txn);

event.put("account", account);

epruntime.sendevent(event,"txnevent");

一个示例语句可以如下:

select account.id, account.rate *txn.amount

from txnevent.win:time(60 sec)

group by account.id

你的映射事件类型可以声明一个或者多个超类。

映射事件的超类也必须是映射事件类型。超类的所有属性名和类型在子类中都可以获取,并且是同名覆盖。此外,在epl中使用超类的地方,子类的对象也可以匹配该表达式。

下面accountupdate有一个baseupdate超类。

   addeventtype("accountupdate", accountupdatedef,

   new string[] {"baseupdate"});

下面是epl语句,子类对象都可以匹配:

// receive baseupdate and any subtypesincluding subtypes of subtypes

select * from baseupdate

下面通过一个示例说明映射事件的嵌套属性。

事件类型的定义:

map<string, object> updatedfielddef =new hashmap<string, object>();

updatedfielddef.put("name",string.class);

updatedfielddef.put("addressline1",string.class);

updatedfielddef.put("history",updatehistory.class);

   addeventtype("updatedfieldtype", updatedfielddef);

map<string, object> accountupdatedef= new hashmap<string, object>();

accountupdatedef.put("accountid",long.class);

accountupdatedef.put("fields","updatedfieldtype");

// the latter can also be:  accountupdatedef.put("fields",updatedfielddef);

addeventtype("accountupdate",accountupdatedef);

定义和发送事件:

map<string, object> updatedfield =new hashmap<string, object>();

updatedfield.put("name","joe doe");

updatedfield.put("addressline1","40 popular street");

updatedfield.put("history", newupdatehistory());

map<string, object> accountupdate =new hashmap<string, object>();

accountupdate.put("accountid",10009901);

accountupdate.put("fields",updatedfield);

epservice.getepruntime().sendevent(accountupdate,"accountupdate");

最后查询事件:

select accountid, fields.name, fields.addressline1,fields.history.lastupdate

from accountupdate

使用数组作为属性。

map<string, object> sale = newhashmap<string, object>();

sale.put("userids", int[].class);

sale.put("salespersons",salesperson[].class);

sale.put("items","orderitem[]");  // theproperty type is the name itself appended by []

   addeventtype("saleevent", sale);

select userids[0], salespersons[1].name,

   items[1], items[1].price.amount from saleevent