Эспер считает повторяющиеся события по образцу

У меня есть последовательность событий, которая выглядит следующим образом:

  1. Событие А запускает последовательность
  2. Произошло несколько событий B
  3. Событие C останавливает последовательность

Я сделал это с шаблоном [каждый A -> (B до C)], это кажется правильным (как вы думаете?). Но я изо всех сил пытаюсь получить и собрать информацию из событий B, которые возникли в последовательности. Я хотел бы просто иметь подсчет и, возможно, некоторые средние значения, но, похоже, ничего не работает (пример 1 возвращает 1, пример 2 возвращает 0, а пример 3 возвращает ноль, даже если мои события 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"))
    )
]

person Gaetan L.    schedule 15.06.2016    source источник


Ответы (2)


Я бы выбрал другой подход для этого варианта использования и использовал бы контекст вместо шаблона:

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), но для расширенного использования я бы рекомендовал более подробную документацию esper 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). Будет выведено только последнее событие (без последнего ключевого слова здесь будет выведено каждое событие, полученное, когда раздел был активен). В этом примере будет выведено количество событий, полученных за время существования контекстного раздела, и среднее значение фрагмента «скорости» в EventB.

Обратите внимание, что здесь нет необходимости выполнять какую-либо фильтрацию по источнику, поскольку контекст уже разделяет события EventCreated по источнику.

person TyrManuZ    schedule 15.06.2016
comment
Спасибо за ваш ответ, я читаю документацию esper и пытаюсь написать контекст, но я уже пытаюсь перевести свой шаблон. Видите ли, я упростил свой пример, сказав, что события B и C должны иметь тот же источник, что и A, но на самом деле у них больше свойств для проверки (я отредактировал свой исходный пост), и на данный момент я не могу воспроизвести getString/getNumber функции в моем контексте. - person Gaetan L.; 16.06.2016
comment
Кроме того, как насчет условного счета? Что-то вроде e.countOf(event -> getNumber(event, c8y_HarshBehavior.speed) › 100), за исключением того, что это не работает. - person Gaetan L.; 16.06.2016
comment
Я бы поставил getNumber(event, c8y_HarshBehavior.speed) › 100 в предложение where - person TyrManuZ; 16.06.2016
comment
Я не могу этого сделать, мне нужно много чего посчитать... Например, мне нужна средняя скорость, а также количество событий, где скорость была > 100, сколько раз она была между 50 и 10 и т. д. - person Gaetan L.; 16.06.2016
comment
Только что нашел пример в шаблонах решения esper. Вы можете использовать счетчик следующим образом: count(*, getNumber(event, "c8y_HarshBehavior.speed") > 100). Только что попробовал, и это работает. Это учитывается только в том случае, если логическое выражение истинно. - person TyrManuZ; 16.06.2016
comment
Как насчет e.selectFrom(e -> .....).countOf(). Вы всегда можете связать их. - person user3613754; 16.06.2016
comment
Это должно быть e.where(e -> ... filter..).countOf() - person user3613754; 16.06.2016
comment
count(*, event.speed >= 100.0) сделал свое дело, спасибо :) e.where не вернул ожидаемого результата (вернул 0). - person Gaetan L.; 16.06.2016
comment
В первом подходе с шаблоном B возвращает массив, а B.where(b -> ....).countOf() фильтрует и подсчитывает этот массив. - person goodie; 17.06.2016

Я не эксперт, но "count()" никогда не возвращает "null". Ваше наблюдение, вероятно, неверно в этом отношении. «count()» — это функция агрегирования, которая подсчитывает количество вхождений того, что находится в предложениях from. Для шаблонов подсчитывается количество совпадений с шаблоном.

"count(B)" подсчитывает количество (различных) ненулевых значений в выражении, см. документ. Это также не возвращает «ноль».

«Пример 3» - это то, что вам нужно, просто убедитесь, что на самом деле есть несколько событий B, прибывающих до событий C, в соответствии с вашими тестовыми данными.

person user3613754    schedule 15.06.2016
comment
Плохо, вы правы, пример 1 (count(*)) логически возвращает 1, так как весь шаблон совпал один раз. Пример 2 (count(B)) возвращает 0, а пример 3 (B.countOf()) возвращает null, так как события B не были созданы. Однако это не так, были события Б. - person Gaetan L.; 16.06.2016
comment
Упростите оператор и разместите здесь пример, в котором используется инструмент EPL. Ссылка на инструмент EPL: esper-epl-tryout.appspot.com/epltryout/mainform. .html - person user3613754; 16.06.2016