使用超时用 siddhi 编写 "arrived" 和 "departed" 查询
Writing an "arrived" and "departed" query with siddhi using timeouts
我希望在我的应用程序中用 Siddhi 替换 Esper。现在的 esper 语句是一个“超时”类型模式,我需要在具有唯一“名称”和“类型”(我可以在传入事件中查找的字符串值)的事件到达和离开时报告。当事件第一次到达我的 firstunique window 时,我知道该事件已经到达,如果我没有看到任何同名事件并在用户定义的超时值中键入,我假设该事件已经结束。这是我的 esper 语句的样子(请注意,实际的 esper 中还有很多内容,我只是为了示例而简化了它):
create window events_1.std:firstunique(name, type) as NameEvent
insert into events_1 select * from EventCycle[events]
on pattern [every event1=events_1->(timer:interval(4.0 sec) and not events_1(name=event1.name, type=event1.type))]delete from events_1 where name = event1.name AND type=event1.type
然后我 select 来自 events_1 的 irstream 并通过获取传入和删除的事件我然后从 window 获取“到达”和“离开”事件。
对于 siddhi,firstunique window 相当简单(我认为?):
from EventCycle#window.firstUnique('name')[ type=='type' ] select name, type insert into NameEvent
但我真的对如何用 Siddhi 替换那个 esper “on pattern” 一无所知。我可以为此使用一个“from every”语句吗?还是我需要对 Siddhi 使用不同的方法?
任何帮助我走上正确道路的人都将不胜感激!
实现您的要求的一种方法是检查事件是否发生。
恐怕,AFAIK,WSO2 CEP-3.1.0 不支持未发生检查。
然而,它在 WSO2 CEP-4.0.0 中得到支持(我在 2015 年 8 月 24 日撰写本文时尚未发布)。
可以参考不发生检测样本[1].
解释:
这里,如果没有唯一事件发生,我们将离开第一个事件 4 秒(这是超时),因为最近的唯一事件已经发生。
所以看起来我们需要检查事件是否发生。
在CEP 4.0.0中,您可以通过以下方式实现您的需求:
from EventCycle#window.firstUnique(name)[ type=='type' ]
select name, type
insert into NameEvents; -- Note: I renamed NameEvent in the question to NameEvents
-- After seeing the latest unique event (Query-A), 4 seconds later (Query-B), we're checking if no unique event has occured in between (Query-C and Query-D).
-- So, we're checking the non-occurance of an event here... See link [1] for a sample.
--Query-A
from EventCycle#window.unique(name)[ type=='type' ]
select name, type
insert into latestEvents;
-- Query-B
from latestEvents#window.time(4 seconds) -- Here, I've taken 4 seconds as the timeout.
select *
insert expired events into timedoutEvents;
-- Query-C
from every latestEvent = latestEvents[ type=='type' ] ->
keepAliveEvent = latestEvents[ latestEvent.name == keepAliveEvent.name and type=='type' ]
or timedoutEvent = timedoutEvents[ latestEvent.name == timedoutEvent.name and type=='type' ]
select latestEvent.name as name, keepAliveEvent.name as keepAliveName
insert into filteredEvents;
-- Query-D
from filteredEvents [ isNull(keepAliveName)]
select name
insert into departedLatestEvents;
-- Since we want the name from the NameEvents stream, we're joining it with the departedLatestEvents stream
from departedLatestEvents#window.length(1) as departedLatestEvent join
NameEvents#window.length(1) as NameEvent
on departedLatestEvent.name == NameEvent.name -- not checking type as both departedLatestEvents and NameEvents have events only with type 'type'
select NameEvent.name as name, 'type' as type
insert into departedFirstEvents;
Link 代码示例中引用:
1 https://docs.wso2.com/display/CEP400/Sample+0111+-+Detecting+non-occurrences+with+Patterns
希望对您有所帮助!
我希望在我的应用程序中用 Siddhi 替换 Esper。现在的 esper 语句是一个“超时”类型模式,我需要在具有唯一“名称”和“类型”(我可以在传入事件中查找的字符串值)的事件到达和离开时报告。当事件第一次到达我的 firstunique window 时,我知道该事件已经到达,如果我没有看到任何同名事件并在用户定义的超时值中键入,我假设该事件已经结束。这是我的 esper 语句的样子(请注意,实际的 esper 中还有很多内容,我只是为了示例而简化了它):
create window events_1.std:firstunique(name, type) as NameEvent
insert into events_1 select * from EventCycle[events]
on pattern [every event1=events_1->(timer:interval(4.0 sec) and not events_1(name=event1.name, type=event1.type))]delete from events_1 where name = event1.name AND type=event1.type
然后我 select 来自 events_1 的 irstream 并通过获取传入和删除的事件我然后从 window 获取“到达”和“离开”事件。
对于 siddhi,firstunique window 相当简单(我认为?):
from EventCycle#window.firstUnique('name')[ type=='type' ] select name, type insert into NameEvent
但我真的对如何用 Siddhi 替换那个 esper “on pattern” 一无所知。我可以为此使用一个“from every”语句吗?还是我需要对 Siddhi 使用不同的方法?
任何帮助我走上正确道路的人都将不胜感激!
实现您的要求的一种方法是检查事件是否发生。
恐怕,AFAIK,WSO2 CEP-3.1.0 不支持未发生检查。
然而,它在 WSO2 CEP-4.0.0 中得到支持(我在 2015 年 8 月 24 日撰写本文时尚未发布)。
可以参考不发生检测样本[1].
解释:
这里,如果没有唯一事件发生,我们将离开第一个事件 4 秒(这是超时),因为最近的唯一事件已经发生。 所以看起来我们需要检查事件是否发生。
在CEP 4.0.0中,您可以通过以下方式实现您的需求:
from EventCycle#window.firstUnique(name)[ type=='type' ]
select name, type
insert into NameEvents; -- Note: I renamed NameEvent in the question to NameEvents
-- After seeing the latest unique event (Query-A), 4 seconds later (Query-B), we're checking if no unique event has occured in between (Query-C and Query-D).
-- So, we're checking the non-occurance of an event here... See link [1] for a sample.
--Query-A
from EventCycle#window.unique(name)[ type=='type' ]
select name, type
insert into latestEvents;
-- Query-B
from latestEvents#window.time(4 seconds) -- Here, I've taken 4 seconds as the timeout.
select *
insert expired events into timedoutEvents;
-- Query-C
from every latestEvent = latestEvents[ type=='type' ] ->
keepAliveEvent = latestEvents[ latestEvent.name == keepAliveEvent.name and type=='type' ]
or timedoutEvent = timedoutEvents[ latestEvent.name == timedoutEvent.name and type=='type' ]
select latestEvent.name as name, keepAliveEvent.name as keepAliveName
insert into filteredEvents;
-- Query-D
from filteredEvents [ isNull(keepAliveName)]
select name
insert into departedLatestEvents;
-- Since we want the name from the NameEvents stream, we're joining it with the departedLatestEvents stream
from departedLatestEvents#window.length(1) as departedLatestEvent join
NameEvents#window.length(1) as NameEvent
on departedLatestEvent.name == NameEvent.name -- not checking type as both departedLatestEvents and NameEvents have events only with type 'type'
select NameEvent.name as name, 'type' as type
insert into departedFirstEvents;
Link 代码示例中引用:
1 https://docs.wso2.com/display/CEP400/Sample+0111+-+Detecting+non-occurrences+with+Patterns
希望对您有所帮助!