Filtering on prior events in Siddhi - complex-event-processing

Is it possible to detect if a prior event happened before a current one in Siddhi? I am trying to do something like "send alert if Y happened after X". I've gotten the inverse of that working (send alert if Y happened without X ever happening) with a query similar to this:
from s1=inStream[value == 'Y'] and
not inStream[value == 'X']
select s1.person
insert into outStream
and was hoping I would be able to make my intended query work by simply removing the "not", however that did not work.

Use the following query
from s1=inStream[value == 'X'] -> s2= inStream[value == 'Y']
select s1.person, s2.person
insert into outStream;
If you want to limit the time between X and Y (which is always recommended), Use
from s1=inStream[value == 'X'] -> s2= inStream[value == 'Y'] within 10 min
select s1.person, s2.person
insert into outStream;

Related

Postgres: How to increment the index (pointer) to access other rows

I have been trying to understand how to increment the reference to some value.
In C I would simply increment the pointer to retrieve a value in the next array location.
How does this mechanism work in Postgres? is it possible?
For an example, I have created a table with some data in:
create table mathtest (
x int, y int, val int)
insert into mathtest (x,y,val)
values (1,1,10),(2,2,20),(3,3,30),(4,4,40),(5,5,50),(6,6,60),(7,7,70),(8,8,80),(9,9,90),(10,10,100),(11,11,110)
What I want to do is add the val value from the current row and then the val value when the x value in the row equals the current x value plus 2, and then plus 4. I realise that I can't assume the next row that is retrieved will be in a set order so I can't use 'lead'
If it was C I would simply increment the pointer.
The data output needs to be when the modulo of x and y = 0 for certain divisors. (this bit works)
select
x base,
(x+2) plus1x,
(x+4) plus2x,
y,
val
from mathtest
where x%2 =0 and y%3 = 0
This outputs the following:
base plus1x plus2x y val
1 6 8 10 6 60
The output I would like is:
60 + 80 +100 = 240
I can't conceptualise how to do it. My mind seems to be stuck in procedural C mode!
Whatever I type and try is an error.
Can any body help me to get over this hurdle?
Welcome to the world of window functions.
You need an explicit ordering, otherwise it makes no sense to speak of the "previous row".
As a simple example, to get the difference to the previous value, you can query like
SELECT val -
lag(val) OVER (ORDER BY x)
FROM mathtest;

MDX Calculated member filter by dimension attribute and member value

I have MDX (similar to one questioned and answered here):
(
[PX Market].[PX MARKET NAME].&[Elbas],
[Measures].[PX QUANTITY]
)
It works for me (it filters measures to value "Elbas" only). But I need another filtering - to have only values which are < or > than 0. There shoud be some condition similar to "[Measures].[PX QUANTITY] < 0". But I do not know how to implement it.
Thank for any of your advice.
Ondra
Table looks similar like this:
PX_MARKET_NAME; PX_QUANTITY
Elbas; 5
Elbas; -3
Elspot; 4
In result I need only 2nd value (-3). Which belongs to Elbas and is smaller then 0.
So far I tried this, but it is now working :(
FILTER
(
[PX Market].[PX MARKET NAME].&[Elbas],
[Measures].[PX PURCHASE]
) < 0
Try that:
IIF(
([PX Market].[PX MARKET NAME].&[Elbas],[Measures].[PX QUANTITY]) < 0,
([PX Market].[PX MARKET NAME].&[Elbas],[Measures].[PX QUANTITY]),
NULL
)

Drools : Rule firing multiple times

I'm new to Drools and have hit a problem.
I've simplified the rule to exhibit the problem:
rule "test"
when
$ev : TestEvent()
$evList : ArrayList( size >= 3 ) from collect
(
TestEvent(linkId == $ev.getLinkId())
)
then
System.out.println("Rule fired!")
end
Basically, I want to count Events occurring on a particular Link (a Link is a section of road). When 3 events occur on the same Link I want the rule to fire.
The rule above is almost working, but when it fires, it fires 3 times, once for each event. I only want it to fire once.
What am I missing?
Many thanks in advance.
The first pattern picks any TestEvent irrespective of its linkId. If there are n TestEvent facts with a certain linkId, the acivation proceeds n times.
To restrict this rule to fire once you could select a single TestEvent out of any such group of n. Any attribute with a unique ordered value may be used, and if you have events also the event timestamp is available.
rule "test"
when
$ev: TestEvent( $lid: linkId )
not TestEvent( linkId == $lid, this before $ev )
$evList : ArrayList( size >= 3 ) from collect
(
TestEvent(linkId == $lid)
)
then
System.out.println("Rule fired!")
end
I got this working by changing my approach to the problem. I've created Link objects now and then tie the events back to the Link.
The rule ends up
rule "test"
when
$link : Link()
$events : ArrayList( size >= 3 ) from collect (TestEvent(link == $link))
then
System.out.println("Rule fired!")
end
This only fires once per link which is what I need.

EF 6 get two after two before

Let's say I am executing a search in for in DbContext.Cars where x=> x.Id = 1. I would like to do that and then grab two Cars after and two Carsbefore.
How would I do that?
Linq is just using the logic you tell it. So you just change the logic.
DbContext.Cars.Where(car => car.Id >=1 && car.Id <= 5);
The previous gets all car = 3, plus cars 1 and 2, and 4 and 5. So you could also write that:
var carNum = 3;
DbContext.Cars.Where(car => car.Id >= carNum-2 && car.Id <= carNum + 2);
This of course assumes that cars are ordered in numerical order, which you can do in your query. And that there are no missing id's. You could also do this:
DbContext.Cars.Where(/*logic to find first record, subtracting 2*/).Take(5);
In the above, you figure out some logic to find out what your first car is, then figure out what car -2 is, then you take 5 cars, which gets the 2 previous, the car you want, and the two after.
Since you did not provide enough information to determine how your data model works, this is really the best we can do, is give you information to help you figure out the logic yourself.
If you're sure that Id is an integer, you could do the following:
DbContext.Cars.Where(car => Math.Abs(1 - car.Id) <= 2);
If your id sequence has gaps and you want to ensure that you always get the 2 cars with the closest Ids greater than and less than your specified value, you can do:
var carNum = 6;
DbContext.Cars
.Where(car => car.Id < carNum)
.OrderByDescending(car => car.Id)
.Take(2)
.Union(DbContext.Cars
.Where(car => car.Id > carNum)
.OrderBy(car => car.Id)
.Take(2)
)
// If you'd like to also get the car with Id == carNum, uncomment the following
// .Union(DbContext.Cars.Where(car => car.Id == carNum))
;

In Linq to EF 4.0, I want to return rows matching a list or all rows if the list is empty. How do I do this in an elegant way?

This sort of thing:
Dim MatchingValues() As Integer = {5, 6, 7}
Return From e in context.entity
Where MatchingValues.Contains(e.Id)
...works great. However, in my case, the values in MatchingValues are provided by the user. If none are provided, all rows ought to be returned. It would be wonderful if I could do this:
Return From e in context.entity
Where (MatchingValues.Length = 0) OrElse (MatchingValues.Contains(e.Id))
Alas, the array length test cannot be converted to SQL. I could, of course, code this:
If MatchingValues.Length = 0 Then
Return From e in context.entity
Else
Return From e in context.entity
Where MatchingValues.Contains(e.Id)
End If
This solution doesn't scale well. My application needs to work with 5 such lists, which means I'd need to code 32 queries, one for every situation.
I could also fill MatchingValues with every existing value when the user doesn't want to use the filter. However, there could be thousands of values in each of the five lists. Again, that's not optimal.
There must be a better way. Ideas?
Give this a try: (Sorry for the C# code, but you get the idea)
IQueryable<T> query = context.Entity;
if (matchingValues.Length < 0) {
query = query.Where(e => matchingValues.Contains(e.Id));
}
You could do this with the other lists aswell.