Flink CEP 匹配后跳过策略

本文详细介绍了Flink CEP中的匹配跳过策略,包括NO_SKIP、SKIP_TO_NEXT、SKIP_PAST_LAST_EVENT、SKIP_TO_FIRST和SKIP_TO_LAST,通过实例解析了它们在不同场景下的应用,帮助理解如何在复杂事件处理中有效地控制匹配结果的生成。

我们举例来说明不同的跳过策略。例如我们要检测的复杂事件模式为:开始是用户名为 a 的事件(简写为事件 a,下同),可以重复一次或多次;然后跟着一个用户名为 b 的事件,a 事件和 b 事件之间可以有其他事件(宽松近邻)。用简写形式可以直接写作:“a+ followedBy b”。在代码中定义 Pattern 如下:

Pattern. < Event > begin("a").where(new SimpleCondition < Event > () {
    @Override
    public boolean filter(Event value) throws Exception {
        return value.user.equals("a");
    }
}).oneOrMore().followedBy("b").where(new SimpleCondition < Event > () {
    @Override
    public boolean filter(Event value) throws Exception {
        return value.user.equals("b");
    }
});
1
2
3
4
5
6
7
8
9
10
11
我们如果输入事件序列“a a a b”——这里为了区分前后不同的 a 事件,可以记作“a1 a2 a3 b”——那么应该检测到 6 个匹配结果:(a1 a2 a3 b),(a1 a2 b),(a1 b),(a2 a3 b),(a2 b),(a3 b)。如果在初始模式的量词.oneOrMore()后加上.greedy()定义为贪心匹配,那么结果就是:(a1 a2 a3 b),(a2 a3 b),(a3 b),每个事件作为开头只会出现一次。

接下来我们讨论不同跳过策略对匹配结果的影响:
1) 不跳过(NO_SKIP)
代码调用 AfterMatchSkipStrategy.noSkip()。这是默认策略,所有可能的匹配都会输出。所以这里会输出完整的 6 个匹配。

2) 跳至下一个(SKIP_TO_NEXT)
代码调用 AfterMatchSkipStrategy.skipToNext()。找到一个 a1 开始的最大匹配之后,跳过a1 开始的所有其他匹配,直接从下一个 a2 开始匹配起。当然 a2 也是如此跳过其他匹配。最终得到(a1 a2 a3 b),(a2 a3 b),(a3 b)。可以看到,这种跳过策略跟使用.greedy()效果是相同的。

3) 跳过所有子匹配(SKIP_PAST_LAST_EVENT)
代码调用 AfterMatchSkipStrategy.skipPastLastEvent()。找到 a1 开始的匹配(a1 a2 a3 b)之后,直接跳过所有 a1 直到 a3 开头的匹配,相当于把这些子匹配都跳过了。最终得到(a1 a2 a3 b),这是最为精简的跳过策略。

4) 跳至第一个(SKIP_TO_FIRST[a])
代码调用 AfterMatchSkipStrategy.skipToFirst(“a”),这里传入一个参数,指明跳至哪个模式的第一个匹配事件。找到 a1 开始的匹配(a1 a2 a3 b)后,跳到以最开始一个 a(也就是 a1)为开始的匹配,相当于只留下 a1 开始的匹配。最终得到(a1 a2 a3 b),(a1 a2 b),(a1 b)。

5) 跳至最后一个(SKIP_TO_LAST[a])
代码调用 AfterMatchSkipStrategy.skipToLast(“a”),同样传入一个参数,指明跳至哪个模式的最后一个匹配事件。找到 a1 开始的匹配(a1 a2 a3 b)后,跳过所有 a1、a2 开始的匹配,跳到以最后一个 a(也就是 a3)为开始的匹配。最终得到(a1 a2 a3 b),(a3 b)。

-----------------------------------------------------------------------------------------------------------------------------------------------

### Flink CEP 匹配跳过策略选项 Flink CEP 提供了多种匹配跳过策略(After Match Skip Strategy),用于控制在找到一个完整匹配之后如何继续进行新的匹配过程。以下是支持的策略选项及其详细说明: 1. **`noSkip()`** 每个成功的匹配都会被输出,且不会丢弃任何部分匹配结果[^1]。这意味着所有可能的匹配组合都将被保留并输出。 2. **`skipToNext()`** 丢弃以相同事件开始的所有部分匹配[^1]。具体来说,匹配成功后,从当前匹配序列的第一个事件的下一个事件开始进行下一次匹配[^2]。 3. **`skipPastLastEvent()`** 丢弃起始在这个匹配的开始和结束之间的所有部分匹配[^1]。匹配成功后,从当前匹配序列的最后一个事件的下一个事件开始进行下一次匹配[^2]。 4. **`skipToFirst(patternName)`** 丢弃起始在这个匹配的开始和第一个出现的名称为 `PatternName` 的事件之间的所有部分匹配[^1]。需要指定一个合法的 `PatternName`,匹配成功后,从指定模式变量的第一行继续模式匹配[^2]。 5. **`skipToLast(patternName)`** 丢弃起始在这个匹配的开始和最后一个出现的名称为 `PatternName` 的事件之间的所有部分匹配。同样需要指定一个合法的 `PatternName`,匹配成功后,从指定模式变量的最后一行继续模式匹配。 关于用户提到的其他选项: - **`SKIP_TO_START`** 和 **`NO_SKIP_A`** 并未在 Flink CEP 的官方文档或引用中提及,可能是误写或自定义实现。 - **`SKIP_TO_END`** 同样未在现有引用中找到明确描述,可能与 `skipPastLastEvent()` 的行为类似,但需进一步确认。 以下是一个使用 Flink CEP 匹配跳过策略的代码示例: ```java import org.apache.flink.cep.pattern.Pattern; import org.apache.flink.cep.pattern.conditions.SimpleCondition; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.api.datastream.DataStream; public class FlinkCEPExample { public static void main(String[] args) throws Exception { StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); DataStream<Event> input = ...; // 初始化输入数据流 Pattern<Event, ?> pattern = Pattern.<Event>begin("start") .where(new SimpleCondition<Event>() { @Override public boolean filter(Event event) { return event.getName().equals("A"); } }) .next("middle") .where(new SimpleCondition<Event>() { @Override public boolean filter(Event event) { return event.getName().equals("B"); } }) .next("end") .where(new SimpleCondition<Event>() { @Override public boolean filter(Event event) { return event.getName().equals("C"); } }) .afterMatchSkipStrategy(AfterMatchSkipStrategy.skipToNext()); // 设置匹配跳过策略 // 执行模式检测逻辑 ... } } ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值