Esper 以模式计算重复事件

Esper counting repeating events in pattern

我有一系列事件是这样的:

  1. 事件 A 开始序列
  2. 多个事件 B 发生
  3. 事件 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 事件之前到达。