Apache flink 弗林克CEP贪婪匹配

Apache flink 弗林克CEP贪婪匹配,apache-flink,flink-cep,Apache Flink,Flink Cep,我和Flink CEP贪婪的操作员有点争执 给出以下java代码: final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); List<String> strings = Arrays.asList("1,3,5,5,5,5,6,".split(",")); DataStream<String> input = env

我和Flink CEP贪婪的操作员有点争执

给出以下java代码:

    final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

    List<String> strings = Arrays.asList("1,3,5,5,5,5,6,".split(","));

    DataStream<String> input = env.fromCollection(strings);

    Pattern<String, ?> pattern = Pattern.<String>
    begin("start").where(new SimpleCondition<String>() {
        @Override
        public boolean filter(String value) throws Exception {
            return value.equals("5");
        }
    }).oneOrMore().greedy()
    .followedBy("end").where(new SimpleCondition<String>() {

        @Override
        public boolean filter(String value) throws Exception {
            return value.equals("6");
        }
    });

    PatternStream<String> patternStream = CEP.pattern(input, pattern);

    DataStream<String> result = patternStream.select(new PatternSelectFunction<String, String>() {
        @Override
        public String select(Map<String, List<String>> pattern) throws Exception {
            System.err.println("=======");
            pattern.values().forEach(match -> match.forEach(event -> System.err.println(event)));
            System.err.println("=======");
            return "-";
        }
    });

    result.print();
    env.execute("Flink Streaming Java API Skeleton");
final StreamExecutionEnvironment env=StreamExecutionEnvironment.getExecutionEnvironment();
列表字符串=array.asList(“1,3,5,5,5,6,”.split(“,”));
数据流输入=env.fromCollection(字符串);
图案。
开始(“开始”)。其中(新的SimpleCondition(){
@凌驾
公共布尔筛选器(字符串值)引发异常{
返回值。等于(“5”);
}
}).oneOrMore().greedy()
.followerdby(“end”).where(新的SimpleCondition(){
@凌驾
公共布尔筛选器(字符串值)引发异常{
返回值。等于(“6”);
}
});
PatternStream PatternStream=CEP.pattern(输入,pattern);
DataStream result=patternStream.select(新的PatternSelectFunction(){
@凌驾
公共字符串选择(映射模式)引发异常{
System.err.println(“==========”);
pattern.values().forEach(match->match.forEach(event->System.err.println(event));
System.err.println(“==========”);
返回“-”;
}
});
result.print();
execute(“Flink流式Java API框架”);
我想看到:只有“5 5 6”发出

但是,它与“5 5 6”、“5 5 6”、“5 5 6”、“5 6”匹配

如果我这样做:

    begin("start").where(new SimpleCondition<String>() {
        @Override
        public boolean filter(String value) throws Exception {
            return value.equals("3");
        }
    }).followedBy("middle").where(new SimpleCondition<String>() {
        @Override
        public boolean filter(String value) throws Exception {
            return value.equals("5");
        }
    }).oneOrMore().greedy()
    .followedBy("end").where(new SimpleCondition<String>() {

        @Override
        public boolean filter(String value) throws Exception {
            return value.equals("6");
        }
    });
begin(“start”)。其中(新的SimpleCondition(){
@凌驾
公共布尔筛选器(字符串值)引发异常{
返回值。等于(“3”);
}
}).followerdby(“middle”).where(新的SimpleCondition(){
@凌驾
公共布尔筛选器(字符串值)引发异常{
返回值。等于(“5”);
}
}).oneOrMore().greedy()
.followerdby(“end”).where(新的SimpleCondition(){
@凌驾
公共布尔筛选器(字符串值)引发异常{
返回值。等于(“6”);
}
});
然而,(因此提供了一个不同的起始匹配)贪婪操作符通过发出“356”来按预期工作

有没有可能让一个贪婪的匹配者在没有不同启动模式的情况下抓取所有的匹配

还是我遗漏了什么


Stephan

感谢Chesnay Schepler的上述评论:


有一个关于贪婪匹配的已知bug可以解释这种行为:issues.apache.org/jira/browse/FLINK-8914


我暂时将此作为答案。

要控制一个事件将分配多少个匹配项,需要指定名为AfterMatchSkipStrategy的跳过策略

使用Pattern.begin(“start”,AfterMatchSkipStrategy.SkipAstLastEvent())

final StreamExecutionEnvironment env=StreamExecutionEnvironment.getExecutionEnvironment();
列表字符串=array.asList(“1,3,5,5,5,6,”.split(“,”));
数据流输入=env.fromCollection(字符串);
图案。
begin(“start”,aftermatchSkipsStrategy.SkipAstLastEvent())。其中(新的SimpleCondition()){
@凌驾
公共布尔筛选器(字符串值)引发异常{
返回值。等于(“5”);
}
}).oneOrMore().greedy()
.followerdby(“end”).where(新的SimpleCondition(){
@凌驾
公共布尔筛选器(字符串值)引发异常{
返回值。等于(“6”);
}
});
PatternStream PatternStream=CEP.pattern(输入,pattern);
DataStream result=patternStream.select(新的PatternSelectFunction(){
@凌驾
公共字符串选择(映射模式)引发异常{
System.err.println(“==========”);
pattern.values().forEach(match->match.forEach(event->System.err.println(event));
System.err.println(“==========”);
返回“-”;
}
});
result.print();
execute(“Flink流式Java API框架”);

我一直在使用org.apache.flink.cep.nfa.nfa类及其过程(..)方法。查看:根据策略丢弃计算状态(计算状态、结果、赛后策略);我唯一感兴趣的结果是结果[0]。玩代码,看起来“afterMatchSkipStrategy”不会让我只得到最大的匹配。你是否尝试过使用
。直到
替换
。然后是
之后的
。oneOrMore()。greedy()
?谢谢Leyla。我已经尝试过了,并尝试了更多的使用方法,但我仍在发布非贪婪匹配。我觉得在我对CEP引擎实现的理解中遗漏了一些东西,因为这似乎是一个相当常见的用例,不是吗?Stephandi您是否找到解决方案/了解其工作原理?我面临着类似的问题。例如,如果您使用GlobalWindow和自定义触发器,您可能会逐出消息5,5,5,6这一概念在Flink Cep中不适用吗?贪婪匹配有一个已知错误可以解释这种行为:
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

List<String> strings = Arrays.asList("1,3,5,5,5,5,6,".split(","));

DataStream<String> input = env.fromCollection(strings);

Pattern<String, ?> pattern = Pattern.<String>
        begin("start", AfterMatchSkipStrategy.skipPastLastEvent()).where(new SimpleCondition<String>() {
  @Override
  public boolean filter(String value) throws Exception {
    return value.equals("5");
  }
}).oneOrMore().greedy()
        .followedBy("end").where(new SimpleCondition<String>() {
          @Override
          public boolean filter(String value) throws Exception {
            return value.equals("6");
          }
        });

PatternStream<String> patternStream = CEP.pattern(input, pattern);

DataStream<String> result = patternStream.select(new PatternSelectFunction<String, String>() {
  @Override
  public String select(Map<String, List<String>> pattern) throws Exception {
    System.err.println("=======");
    pattern.values().forEach(match -> match.forEach(event -> System.err.println(event)));
    System.err.println("=======");
    return "-";
  }
});

result.print();
env.execute("Flink Streaming Java API Skeleton");