Esper 以模式计算重复事件
Esper counting repeating events in pattern
我有一系列事件是这样的:
- 事件 A 开始序列
- 多个事件 B 发生
- 事件 C 停止序列
我用一个模式 [每个 A -> (B 直到 C)] 来做这件事,它似乎是正确的(你觉得怎么样?)。但我正在努力从序列中出现的 B 事件中检索和汇总信息。我想简单地计算一下,也许还有一些平均值,但似乎没有任何效果(example1 returns 1,example 2 returns 0 和 example 3 return null,即使我的B 事件存在)。
insert into CreateMeasurement
select
C.source as source,
"carDrivingAnalyse" as type,
C.time as time,
{
"example1", count(*),
"example2", count(B),
"example3", B.countOf()
} as fragments
from pattern [
every A = EventCreated(
type = "Ignition",
getString(A, "Ignition.status") = "ON")
-> (
B = EventCreated(
type = "DrivingEvent",
source = A.source,
getString(B, "DrivingEvent.prop1") = getString(A, "Ignition.prop1"),
getNumber(B, "DrivingEvent.prop2") = getNumber(A, "Ignition.prop2"))
until C = EventCreated(
type = "Ignition",
getString(C, "Ignition.status") = "OFF",
source = A.source,
getString(C, "Ignition.prop1") = getString(A, "Ignition.prop1"),
getNumber(C, "Ignition.prop2") = getNumber(A, "Ignition.prop2"))
)
]
我会为这个用例选择不同的方法并使用上下文而不是模式:
create context EventContext
context PartionBySource
partition by event.source.value from EventCreated,
context ContextBorders
initiated by EventCreated(type="EventA") as startEvent
terminated by EventCreated(event.type="EventC");
它已经是一个更复杂的上下文,因为它使用了两个嵌套的上下文。这是 Cumulocity 文档中对上下文的一些基本介绍 (http://cumulocity.com/guides/event-language/advanced/#contexts) but for this advanced usage I would recommend the more detailed esper documentation http://www.espertech.com/esper/release-5.3.0/esper-reference/html/context.html
总而言之,这个上下文是这样做的:
基于 EventCreated 流,它将首先按事件的源设备对事件进行分区。每次有 EventA 时,它都会创建一个新的上下文分区(仅当此时没有此设备的上下文分区时)。随着 EventC 的到来,此设备的上下文分区将结束。
现在您可以像这样使用此上下文:
context EventContext
select
count(*) as count,
avg(getNumber(e, "speed")) as speed
from EventCreated e
where e.event.type = "EventB"
output last when terminated;
此语句使用上下文。它将在上下文分区结束时输出结果(因此当 EventC 到达时)。它只会输出最后一个事件(这里没有 last 关键字,它将输出分区处于活动状态时收到的每个事件)。
在本例中,它将输出在上下文分区存在期间接收到的事件数和 EventB 中 "speed" 片段的平均值。
请注意,这里没有必要按源进行任何过滤,因为上下文已经按源对 EventCreated 上的事件进行了分区。
我不是专家,但 "count()" 从来没有 return "null"。在这方面你的观察可能是错误的。 "count()" 是一个聚合函数,用于计算 from 子句中任何内容的出现次数。对于模式,它计算模式匹配的数量。
"count(B)" 计算表达式中(不同的)非空值的数量,请参阅文档。那也不 return "null".
"example3" 是您想要的,只需确保根据您的测试数据实际上有多个 B 事件在 C 事件之前到达。
我有一系列事件是这样的:
- 事件 A 开始序列
- 多个事件 B 发生
- 事件 C 停止序列
我用一个模式 [每个 A -> (B 直到 C)] 来做这件事,它似乎是正确的(你觉得怎么样?)。但我正在努力从序列中出现的 B 事件中检索和汇总信息。我想简单地计算一下,也许还有一些平均值,但似乎没有任何效果(example1 returns 1,example 2 returns 0 和 example 3 return null,即使我的B 事件存在)。
insert into CreateMeasurement
select
C.source as source,
"carDrivingAnalyse" as type,
C.time as time,
{
"example1", count(*),
"example2", count(B),
"example3", B.countOf()
} as fragments
from pattern [
every A = EventCreated(
type = "Ignition",
getString(A, "Ignition.status") = "ON")
-> (
B = EventCreated(
type = "DrivingEvent",
source = A.source,
getString(B, "DrivingEvent.prop1") = getString(A, "Ignition.prop1"),
getNumber(B, "DrivingEvent.prop2") = getNumber(A, "Ignition.prop2"))
until C = EventCreated(
type = "Ignition",
getString(C, "Ignition.status") = "OFF",
source = A.source,
getString(C, "Ignition.prop1") = getString(A, "Ignition.prop1"),
getNumber(C, "Ignition.prop2") = getNumber(A, "Ignition.prop2"))
)
]
我会为这个用例选择不同的方法并使用上下文而不是模式:
create context EventContext
context PartionBySource
partition by event.source.value from EventCreated,
context ContextBorders
initiated by EventCreated(type="EventA") as startEvent
terminated by EventCreated(event.type="EventC");
它已经是一个更复杂的上下文,因为它使用了两个嵌套的上下文。这是 Cumulocity 文档中对上下文的一些基本介绍 (http://cumulocity.com/guides/event-language/advanced/#contexts) but for this advanced usage I would recommend the more detailed esper documentation http://www.espertech.com/esper/release-5.3.0/esper-reference/html/context.html
总而言之,这个上下文是这样做的:
基于 EventCreated 流,它将首先按事件的源设备对事件进行分区。每次有 EventA 时,它都会创建一个新的上下文分区(仅当此时没有此设备的上下文分区时)。随着 EventC 的到来,此设备的上下文分区将结束。
现在您可以像这样使用此上下文:
context EventContext
select
count(*) as count,
avg(getNumber(e, "speed")) as speed
from EventCreated e
where e.event.type = "EventB"
output last when terminated;
此语句使用上下文。它将在上下文分区结束时输出结果(因此当 EventC 到达时)。它只会输出最后一个事件(这里没有 last 关键字,它将输出分区处于活动状态时收到的每个事件)。 在本例中,它将输出在上下文分区存在期间接收到的事件数和 EventB 中 "speed" 片段的平均值。
请注意,这里没有必要按源进行任何过滤,因为上下文已经按源对 EventCreated 上的事件进行了分区。
我不是专家,但 "count()" 从来没有 return "null"。在这方面你的观察可能是错误的。 "count()" 是一个聚合函数,用于计算 from 子句中任何内容的出现次数。对于模式,它计算模式匹配的数量。
"count(B)" 计算表达式中(不同的)非空值的数量,请参阅文档。那也不 return "null".
"example3" 是您想要的,只需确保根据您的测试数据实际上有多个 B 事件在 C 事件之前到达。