[ https://issues.apache.org/jira/browse/FLINK-6198?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16032997#comment-16032997 ]
ASF GitHub Bot commented on FLINK-6198: --------------------------------------- Github user dawidwys commented on a diff in the pull request: https://github.com/apache/flink/pull/4041#discussion_r119616280 --- Diff: docs/dev/libs/cep.md --- @@ -246,63 +333,118 @@ pattern.where(event => ... /* some condition */).or(event => ... /* or condition </div> </div> -Next, we can append further states to detect complex patterns. -We can control the contiguity of two succeeding events to be accepted by the pattern. +##### Conditions on Contiguity -Strict contiguity means that two matching events have to be directly the one after the other. -This means that no other events can occur in between. -A strict contiguity pattern state can be created via the `next` method. +FlinkCEP supports the following forms of contiguity between consecutive events: -<div class="codetabs" markdown="1"> -<div data-lang="java" markdown="1"> -{% highlight java %} -Pattern<Event, ?> strictNext = start.next("middle"); -{% endhighlight %} -</div> + 1. Strict Contiguity: which expects all matching events to appear strictly the one after the other, + without any non-matching events in-between. -<div data-lang="scala" markdown="1"> -{% highlight scala %} -val strictNext: Pattern[Event, _] = start.next("middle") -{% endhighlight %} -</div> -</div> + 2. Relaxed Contiguity: which simply ignores non-matching events appearing in-between the matching ones. + + 3. Non-Deterministic Relaxed Contiguity: which further relaxes contiguity by also creating alternative + matches which ignore also matching events. -Non-strict contiguity means that other events are allowed to occur in-between two matching events. -A non-strict contiguity pattern state can be created via the `followedBy` or `followedByAny` method. +To illustrate the above with an example, a pattern sequence `a+ b` (one or more `a`s followed by a `b`) with +input `a1, c, a2, b` will have the following results: + + 1. Strict Contiguity: `a2 b` because there is `c` `a1` and `a2` so `a1` is discarded. + + 2. Relaxed Contiguity: `a1 b` and `a1 a2 b`, as `c` will get simply ignored. + + 3. Non-Deterministic Relaxed Contiguity: `a1 b`, `a2 b` and `a1 a2 b`. + +Contiguity conditions should be specified both within individual (looping) states but also +across states. For looping states (e.g. `oneOrMore()` and `times()`) the default is *relaxed contiguity*. If you want +strict contiguity, you have to explicitly specify it by using the `consecutive()` call, and if you want +*non-deterministic relaxed contiguity* you can use the `allowCombinations()` call. + +### Combining States + +Now that we have seen how an individual state can look, it is time to see how to combine them into a full pattern sequence. + +A pattern sequence has to start with an initial state, as shown below: <div class="codetabs" markdown="1"> <div data-lang="java" markdown="1"> {% highlight java %} -Pattern<Event, ?> nonStrictNext = start.followedBy("middle"); +Pattern<Event, ?> start = Pattern.<Event>begin("start"); {% endhighlight %} </div> <div data-lang="scala" markdown="1"> {% highlight scala %} -val nonStrictNext : Pattern[Event, _] = start.followedBy("middle") +val start : Pattern[Event, _] = Pattern.begin("start") {% endhighlight %} </div> </div> -For non-strict contiguity one can specify if only the first succeeding matching event will be matched, or -all. In the latter case multiple matches will be emitted for the same beginning. +Next, you can append more states to your pattern by specifying the desired *contiguity conditions* between them. +This can be done using: + +1. `next()`, for *strict*, +2. `followedBy()`, for *relaxed*, and +3. `followedByAny()`, for *non-deterministic relaxed* contiguity. + +or + +1. `notNext()`, if you do not want an event type to directly follow another +2. `notFollowedBy()`, if you do not want an event type to be anywhere between two other event types + + +<span class="label label-danger">Attention</span> A pattern sequence cannot end in `notFollowedBy()`. + +<span class="label label-danger">Attention</span> A `NOT` state cannot be preceded by an optional one. <div class="codetabs" markdown="1"> <div data-lang="java" markdown="1"> {% highlight java %} -Pattern<Event, ?> nonStrictNext = start.followedByAny("middle"); + +// strict contiguity +Pattern<Event, ?> strict = start.next("middle").where(...); + +// relaxed contiguity +Pattern<Event, ?> relaxed = start.followedBy("middle").where(...); + +// non-deterministic relaxed contiguity +Pattern<Event, ?> nonDetermin = start.followedByAny("middle").where(...); + +// NOT pattern with strict contiguity +Pattern<Event, ?> strictNot = start.notNext("not").where(...); + +// NOT pattern with relaxed contiguity +Pattern<Event, ?> relaxedNot = start.notFollowedBy("not").where(...); + {% endhighlight %} </div> <div data-lang="scala" markdown="1"> {% highlight scala %} -val nonStrictNext : Pattern[Event, _] = start.followedByAny("middle") + +// strict contiguity +val strict: Pattern[Event, _] = start.next("middle").where(...) + +// relaxed contiguity +val relaxed: Pattern[Event, _] = start.followedBy("middle").where(...) + +// non-deterministic relaxed contiguity +val nonDetermin: Pattern[Event, _] = start.followedByAny("middle").where(...) + +// NOT pattern with strict contiguity +val strictNot: Pattern[Event, _] = start.notNext("not").where(...) + +// NOT pattern with relaxed contiguity +val relaxedNot: Pattern[Event, _] = start.notFollowedBy("not").where(...) + {% endhighlight %} </div> - </div> -It is also possible to define a temporal constraint for the pattern to be valid. -For example, one can define that a pattern should occur within 10 seconds via the `within` method. + +Bear in mind that relaxed contiguity means that only the first succeeding matching event will be matched, while +non-deterministic relaxed contiguity, multiple matches will be emitted for the same beginning. + +Finally, it is also possible to define a temporal constraint for the pattern to be valid. --- End diff -- I would emphasize it applies whole pattern sequence. And if multiple within are applied (even for different states/parts) the shortes one is picked up. > Update the documentation of the CEP library to include all the new features. > ---------------------------------------------------------------------------- > > Key: FLINK-6198 > URL: https://issues.apache.org/jira/browse/FLINK-6198 > Project: Flink > Issue Type: Sub-task > Components: CEP > Affects Versions: 1.3.0 > Reporter: Kostas Kloudas > Assignee: Kostas Kloudas > Priority: Critical > Fix For: 1.3.0 > > > New features to include: > * Iterative Functions > * Quantifiers > * Time handling > * Migration from FilterFunction to IterativeCondition -- This message was sent by Atlassian JIRA (v6.3.15#6346)