Flink CEP greedy条件的理解

Flink 使用介绍相关文档目录

Flink 使用介绍相关文档目录

一句话总结

总的来说,Flink CEP greedy的含义为对于pattern中多个不互斥的条件,优先去匹配哪个。

例如:

  • 条件a:字符串以'a'开头
  • 条件b:字符串长度为3

演示和分析

下面我们分两种情况来测试:

  • pattern为a+(greedy)b。如果元素同时符合a和b条件,一定会被当做a来处理。
  • pattern为a+(非greedy)b。如果元素同时符合a和b条件,可以在一部分结果中当做a,另一部分结果中当做b。

情况1:greedy

完整程序为:

val input = env.fromElements("a", "aa", "aaa", "bbb")

// pattern为a+(greedy)b
val pattern = Pattern.begin[String]("a-label").where(s => s.startsWith("a")).oneOrMore.greedy.next("b-label").where(s => s.length == 3)

val patternStream = CEP.pattern(input, pattern)

patternStream.select(new PatternSelectFunction[String, String] {
  override def select(map: util.Map[String, util.List[String]]): String = {
    val a = map.get("a-label")
    val b = map.get("b-label")
    s"$a - $b"
  }
}).print()

env.execute()

输入统一为:

"a", "aa", "aaa", "bbb"

输出为:

11> [aa, aaa] - [bbb]
12> [aaa] - [bbb]
10> [a, aa, aaa] - [bbb]

情况2:非greedy

程序和情况1相同,但是pattern去掉greedy,如下所示:

val pattern = Pattern.begin[String]("a-label").where(s => s.startsWith("a")).oneOrMore.next("b-label").where(s => s.length == 3)

对于同样的输入,输出为:

1> [a, aa, aaa] - [bbb]
3> [aaa] - [bbb]
12> [aa] - [aaa]
2> [aa, aaa] - [bbb]
11> [a, aa] - [aaa]

我们发现不使用greedy的时候多了两个输出:

12> [aa] - [aaa]
11> [a, aa] - [aaa]

分析

"aaa"这个数据既符合条件a又符合条件b。对于贪婪(greedy)的情况,优先使用条件a来匹配。"aaa"符合条件a,所以greedy匹配的结果中"aaa"元素都必须作为条件a使用。但如果没有指定greedy,"aaa"既可以当做a又可以当做b。这样不使用greedy的时候为什么会多两个输出就不难理解了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。