我需要使用WSO2 CEP 4.1.0对事件实施过滤功能。 我的过滤器存储在PostgreSQL数据库中。
为此,我创建了一个event_table配置,并在此event_table流上加入了我的事件。 我的过滤器可以有默认值,因此我需要一个复杂的连接条件:
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)
(我做一个LEFT OUTER JOIN,因为如果找到过滤器我必须有一个不同的过程:如果我找到过滤器,我用它的信息完成my_stream,并将事件保存在数据库表中;如果没有,我将事件保存在另一个数据库表中。)
问题是当系统提取连接条件以解释它时,它会删除括号,因此布尔解释是错误的:
on filter.field1 == '' OR stream.field1 == filter.field1
AND filter.field2 == '' OR stream.field2 == filter.field2
有没有办法在没有插件创建的情况下实现这种功能?
问候。
编辑:这是我找到的当前解决方案,但我担心性能和复杂性,所以寻找另一个:
#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
答案 0 :(得分:0)
从根本上说,left outer join
可能不适用于事件表。因为事件表不是活动构造(如流)。所以我们不能将窗口分配给事件表。但是,为了与(外连接)连接,每个流应该与窗口相关联。由于我们无法对事件表执行此操作,因此无论如何都不会使用外连接。
但是,要解决您的方案,您可以在没有任何条件的情况下将my_stream
与my_event_table
一起加入,并将结果事件发送到中间流,然后检查该中间流的条件。尝试类似的东西;
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;