Query condition ranges
The
within and
without clauses (see
Query conditions) can each have an optional
between clause that restricts which part of the pattern the
within or
without clause applies to. The format for specifying a range is as follows:
between ( identifer1 identifier2 ... )
At least two identifiers that are specified in the event pattern are required. The identifiers specify a period of time that starts when one of the specified events is received and ends when one of the other specified events is received. A between clause is the only place in which you can specify a coassignment identifier that was assigned in a wait clause. You cannot specify identifiers used in a without clause. Also, the same event cannot match both the coassignment identifier in the without clause and an identifier in a between clause.
The condition that the between clause is part of must occur in the range of identifiers specified in the between clause. For example, consider the following find pattern:
find A as a and B as b and C as c without X as x between ( a b )
For there to be a match set for this pattern, no X event can be added to its window between the arrivals of the a and b events. If events are received in the order B A X C, then there is a match set because the X event is not between the a and b events. If the events are received in the order B C X A, then there is no match set because an X event occurred between the a and b events.
Here is another example:
find A as a -> B as b -> (C as c and D as d)
within 10.0 between (a b)
within 10.0 between (c d)
Range | Description |
(a b) | This duration starts when an A event is received because the pattern is looking for an A event followed by a B event. For there to be a match, the B event must arrive less than 10 seconds after the A event. |
(c d) | After an A event followed by a B event has been received, this duration starts when either a C event or a D event is received. Since the pattern is looking for a C and a D, it does not matter which event is received first. For there to be a match, the event that is not received first must be received less than 10 seconds after the first event. |
The following table provides examples of match sets.
Time | Event Received | Match Set |
10 | A(1) | |
15 | B(1) | |
20 | D(1) | |
25 | C(1) | A(1), B(1), D(1), C(1) |
37 | D(2) | No match. More than 10 seconds elapsed between C(1) and D(2). |
40 | C(2) | A(1), B(1), D(2), C(2) |
The range is exclusive. That is, the range applies only after the first event is received and before the last event is received. For example, consider this pattern:
find A as a1 -> A as a2 without A as repeated between ( a1 a2 )
A match set for this pattern is two consecutive A events. If three consecutive A events are added to the window, the first and third do not constitute a match set event though the first A was followed by the third A. This is because the second A was added between the first and the third A events. In other words, the events that match a1 and a2 are excluded from the range in which the repeated event can match. The following table provides examples of match sets for this pattern. It assumes that A(1) is still in the window when A(4) is added.
Event Added to Window | Match Set | Not a Match Set |
A(1) | | |
A(2) | A(1), A(2) | |
A(3) | A(2), A(3) | A(1), A(3) |
A(4) | A(3), A(4) | A(1), A(4) and A(2), A(4) |
The query below is a real world example of the pattern just discussed. It emits the average price change in the last minute.
query FindAveragePriceMove {
inputs {
Trade() key symbol within 1 minute;
}
find every Trade as t1 -> Trade as t2
without Trade as mid between (t1 t2)
select avg(t2.price - t1.price) as avgPriceChange {
emit AveragePriceChange(symbol, avgPriceChange);
}
}
It is illegal to have two within clauses with identical between ranges. This would be redundant, as only the shortest within duration would have any effect. It is, however, legal to have more than one without clause with the same between range. Typically, these would refer to different event types or where conditions.
If or-terms (see
Query or operator) are included in the range of a condition, then if an or-term is not matched, that coassignment is ignored in the range. If this means that the range has less than two points, the condition is ignored. There must be a combination of events for which there are at least two coassignments definitely in the range. Using only or-terms on opposite sides of an
or operator in the pattern is an error, as the condition will never apply.