简体   繁体   English

WSO2 CEP中event_table的复杂加入条件

[英]Complex joining condition on event_table in WSO2 CEP

I need to implement a filtering feature on events using WSO2 CEP 4.1.0. 我需要使用WSO2 CEP 4.1.0对事件实现过滤功能。 My filters are stored in a PostgreSQL database. 我的过滤器存储在PostgreSQL数据库中。

To do this, I created an event_table configuration, and I join my event on this event_table stream. 为此,我创建了一个event_table配置,并在此event_table流上加入了我的事件。 My filters can have default values, so I need a complex joining condition: 我的过滤器可以具有默认值,因此我需要一个复杂的加入条件:

from my_stream#window.length(1) left outer join my_event_table as filter
    on (filter.field1 == '' OR stream.field1 == filter.field1)
    AND (filter.field2 == '' OR stream.field2 == filter.field2)

(I do a LEFT OUTER JOIN because I must have a different process if the filter is found or not: if I find the filter, I complete my_stream with information from it, and I save the event in database table; if not, I save the event in another database table). (我执行LEFT OUTER JOIN的原因是,无论是否找到过滤器,我都必须有一个不同的过程:如果找到过滤器,则会使用其中的信息完成my_stream的操作,然后将事件保存在数据库表中;如果没有,则保存该事件在另一个数据库表中)。

Problem is when the system extract the join condition to interpret it, it removes the parenthesis, so the boolean interpretation is wrong: 问题是系统提取连接条件对其进行解释时,会删除括号,因此布尔解释是错误的:

on filter.field1 == '' OR stream.field1 == filter.field1
AND filter.field2 == '' OR stream.field2 == filter.field2

Is there a way to implement this kind of feature, without plugin creation? 没有创建插件就可以实现这种功能的方法吗?

Regards. 问候。

EDIT: This is the current solution I found, but I am afraid about performance and complexity, so look for another one: 编辑:这是我发现的当前解决方案,但是我担心性能和复杂性,因此请寻找另一个解决方案:

#first, I left join on my event_table
from my_stream#window.length(1) left outer join my_event_table as filter
        on (filter.field1 == '' OR stream.field1 == filter.field1)
select stream.field1, stream.field2, stream.field3, filter.field1 as filter_field1, filter.field2 as filter_field2, filter.field3 as filter_field3, filter.info1
insert into tempStreamJoinProblemCount

#if the join return nothing, then no filter for my line
from tempStreamJoinProblemCount[filter_field1 IS NULL]
insert into filter_not_found

#if the join return some lines, maybe 1 of these lines can match, I continue to check
from tempStreamJoinProblemCount[NOT filter_field1 IS NULL]
select field1, field2, field3, info1
#I check my complex joining condition and store it in a boolean for later: 1 then my filter match, 0 then no match
convert(
(filter_field2=='' OR field2 == filter_field2)
AND(filter_field3=='' OR field3 == filter_field3),'int') as filterMatch
insert into filterCheck

#if filterMatch is 1, I extract the filter information (info1), else I put a default value (minimal value); custom:ternaryInt is just the ternary function: boolean_condition?value_if_true:value_if_false
from computeFilterMatchInformation
select field1, custom:ternaryInt(filterMatch==1, info1, 0) as info1, filterMatch
insert into filterCheck

#As we did not join on all fields, 1 line has been expanded into several lines, so we group the lines, to remove these generated lines and keep only 1 initial line; 
from filterMatchGroupBy#window.time(10 sec)
#max(info1) return only the filter value (because the value 0 from previous stream is the minimal value);
#sum(filterMatch) return 0 if there is no match, and 1+ if there is a match
select field1, max(info1) as info1, sum(filterMatch) as filter_match
group by field1, field2, field3
insert into filterCheck

#we found no match
from filterCheck[filter_match == 0]
select field1, field2, field3
insert into filter_not_found

#we found a match, so we extract filter information (info1)
from filterCheck[filter_match > 0]
select field1, field2, field3, info1
insert into filter_found

Fundamentally, left outer join might not work with an event table. 从根本上讲, left outer join可能不适用于事件表。 Because event table is not an active construct (like a stream). 因为事件表不是活动构造(如流)。 So we cannot assign a window to an event table. 因此,我们无法将窗口分配给事件表。 However, in order to join with (outer joins) each stream should be associated with a window. 但是,为了与(外部联接)联接,每个流都应与一个窗口关联。 Since we cannot do that with event tables, outer-joins wouldn't work anyway. 由于我们无法使用事件表来执行此操作,因此外部联接无论如何都无法正常工作。

However, to address your scenario, you can join my_stream with my_event_table without any conditions and emit resulting events into an intermediate stream, and then check for the conditions on that intermediate stream. 但是,要解决您的情况,您可以在没有任何条件的情况下将my_streammy_stream结合my_event_table ,并将结果事件发送到中间流中,然后检查该中间流上的条件。 Try something similar to this; 尝试类似的事情;

from my_stream join my_event_table
select 
    my_stream.field1 as streamField1, 
    my_event_table.field1 as tableField1,
    my_stream.field1 as streamField2, 
    my_event_table.field1 as tableField2,
insert into intermediateStream;

from intermediateStream[((tableField1 == '' OR streamField1 == tableField1) AND (tableField2 == '' OR streamField2 == tableField2))]
select *
insert into filtereMatchedStream;

from intermediateStream[not ((tableField1 == '' OR streamField1 == tableField1) AND (tableField2 == '' OR streamField2 == tableField2))]
select *
insert into filtereUnMatchedStream;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM