siddhi
siddhi copied to clipboard
Support more than one logical operator for pattern
Description: There are multiple requests from community users on $subject in https://github.com/siddhi-io/siddhi/issues/1611 , https://github.com/siddhi-io/siddhi/issues/1610 and https://github.com/siddhi-io/siddhi/issues/1461. We need to revisit the pattern implementation/design of Siddhi to achieve this.
@mohanvive @suhothayan Is there any sort of a timeline for this? If you think I can help with something, just let me know.
In #1461 and #1610, some workarounds were given for rewriting queries involving multiple unordered events (in the meantime support for them is added)...but after checking with the simple pattern A and B and C the workaround seems not to be working:
define stream A (value int);
define stream B (value int);
define stream C (value int);
@sink(type='log')
define stream output(msg string);
from A and B select "A and B" as msg insert into o1;
from o1 and C select "A and B and C" as msg insert into output;
I have verified that the above app is not detecting all the possible (ordered) patterns for A, B, and C. For example, the output is not emitting any event for the following inputs:
c1 b1 a1
a1 c1 b1
b1 a1 c1
which looks like a bug to me (on the Siddhi Editor at least, the output triggers only after a1 b1 c1). Could you confirm whether there is a bug here @mohanvive ?
@mohanvive There are basically two workarounds that have worked for me so far:
- Generating all the permutation patterns as discussed in #1610 (and along the lines of the
match_recognizepermuteoperator, see this):
from A -> B -> C select "A and B and C" as msg insert into output;
from A -> C -> B select "A and B and C" as msg insert into output;
from B -> A -> C select "A and B and C" as msg insert into output;
from B -> C -> A select "A and B and C" as msg insert into output;
from C -> A -> B select "A and B and C" as msg insert into output;
from C -> B -> A select "A and B and C" as msg insert into output;
- Using an in-memory table:
define table tableABC(id string);
-- Update state
from A select "A" as id update or insert into tableABC on tableABC.id == id;
from B select "B" as id update or insert into tableABC on tableABC.id == id;
from C select "C" as id update or insert into tableABC on tableABC.id == id;
-- Check conditions on arrival of events
from A[("A" == tableABC.id in tableABC) and ("B" == tableABC.id in tableABC) and ("C" == tableABC.id in tableABC)] select "A and B and C" as msg insert into output;
from B[("A" == tableABC.id in tableABC) and ("B" == tableABC.id in tableABC) and ("C" == tableABC.id in tableABC)] select "A and B and C" as msg insert into output;
from C[("A" == tableABC.id in tableABC) and ("B" == tableABC.id in tableABC) and ("C" == tableABC.id in tableABC)] select "A and B and C" as msg insert into output;
Overall I think option 2 is preferable, since it scales linearly with the number of conditions, whereas option1 requires n! pattern queries in the general case (6 for the case at hand, n=3).
I don't know how the support for multiple logical operator patterns is planned to be implemented, but maybe this table approach can provide some guidelines.
We can use patterns to achieve this A and B and C within 15 mins
define stream RegulatorStream(roomNo int, deviceId long) define stream tempStream (value int); define stream tempStream1 (value int);
@sink(type='log') define stream output(msg string);
from RegulatorStream[roomNo == 24] select 0 as value insert into tempStream;
from RegulatorStream[roomNo == 25] select 1 as value insert into tempStream;
from RegulatorStream[roomNo == 26] select 1 as value insert into tempStream1;
from every e1 = tempStream -> e2 = tempStream[(e1.value == 0 and e2.value == 1) or (e1.value == 1 and e2.value == 0) ] within 15 mins select 0 as value insert into tempStream1;
from every e1 = tempStream1-> e2 = tempStream1[(e1.value == 0 and e2.value == 1) or (e1.value == 1 and e2.value == 0) ] within 15 mins select "alert" as msg insert into outputStream;
@suhothayan What is the current state? Could you please share your thoughts on how to deal with this issue?