MATCH_RECOGNIZE (流分析)
MATCH_RECOGNIZE 子句用于通过数据流搜索一组事件。 通过此子句,可以使用正则表达式和聚合方法来定义事件模式,以验证和提取匹配项中的值。
以下示例演示 MATCH_RECOGNIZE 子句的基本结构:
SELECT *
INTO output FROM input TIMESTAMP BY time
MATCH_RECOGNIZE (
LIMIT DURATION (minute, 1)
PARTITION BY tollBoothId
MEASURES
Last(Toyota.LicensePlate) AS toyotaLicensePlate,
Last(Lexus.LicensePlate) AS lexusLicensePlate
AFTER MATCH SKIP TO NEXT ROW
PATTERN (Toyota+ Ford* Lexus+)
DEFINE
Toyota AS Toyota.make = 'Toyota',
Ford AS Ford.make = 'Ford',
Lexus AS Lexus.make = 'Lexus'
) AS T
MATCH_RECOGNIZE的匹配输出为默认的“每行一行匹配”,这是唯一可用的匹配输出。 这意味着该匹配将为每个匹配生成单个行结果,并且不会返回匹配的行。
语法
SELECT_star_query_definition
MATCH_RECOGNIZE (
LIMIT DURATION (time_unit, time)
PARTITION BY column_alias
MEASURES
expression AS column_alias [,...n]
AFTER MATCH SKIP TO NEXT ROW
PATTERN ( <pattern_group> )
DEFINE
pattern_name AS boolean_expression [,…n]
) AS column_alias
<pattern_group> ::=
{
<pattern_name_modifier> [ | <pattern_group> ]*
}
<pattern_name_modifier> ::=
{
<pattern_atom> [ <pattern_atom> ]*
}
<pattern_atom> ::=
{
[ pattern_name | ( <pattern_group> ) ] [ <pattern_modifier> ]?
}
<pattern_name> :: =
{
name | .
}
<pattern_modifier> ::=
{
* | + | ?
}
限制持续时间
限制持续时间用于定义要搜索的模式的时间窗口。 事件按时间排序,TIMESTAMP BY 可用于 SELECT 子句指定时间字段。
PARTITION BY
PARTITION BY 允许对匹配项进行键键,并按列名进行分区。 将在 partition 语句指定的每个唯一键上发生匹配。 这样,单个查询就可以在所有键上匹配,并生成单独的匹配项(一对一键)。
匹配后跳到下一行
此 skip 子句定义,从事件 S 开始匹配模式后,下一次尝试匹配模式将从事件 S+1 开始。 在这种情况下,匹配项可以重叠,因为一个模式可以包含另一个模式的开头。 这是唯一可用的 skip 子句。
措施
MEASURES 用于使用聚合方法定义匹配项中的投影值。 例如, LAST(A.id) AS aid
将输出在与名为 A
字段名称 aid
的模式匹配的所有事件上找到的最后id
一个值。
分类器函数
分类器函数可用于在 MEASURES 中输出与输入事件匹配的模式名称。 函数返回字符串列表,每个字符串都具有与事件匹配的模式名称。
PATTERN
该模式定义要通过数据流搜索的事件的正则表达式。 模式变量是用户定义的,由空格分隔。 和 等+*修饰符可用于在匹配事件时修改变量的频率。
示例
PATTERN (A+ (B | C))
此示例中的模式至少定义一次变量 A ,后跟 B 或 C 串联。
模式限定符
模式限定符用于更改模式在数据流中的映射方式,定义模式需要匹配的次数才能有效。 以下限定符可用:
- “*”- 零次或更多次
- “+” - 一次或多次
- “?”– 零次或一次
- “|”- 一种或另一种模式
示例:
PATTERN (A? B+)
此示例定义 A 0 或 1 次,后跟 B 至少一次。
定义
DEFINE 指定用于将模式变量与事件匹配的规则。 规则是基于数据流中聚合值的布尔表达式。
DEFINE
A AS Last(A.bigint) > 5,
B AS Last(A.bigint) < B.bigint
此示例定义了 规则 A 和 B ,其中 A 的 LAST 值大于 5,而 B 中的 A 的 LAST 值小于 B 的当前值。如果不对 DEFINE 表达式使用聚合函数,则计算的当前事件会绑定到模式变量,例如,在 B.bigint 上 ,B 值来自正在计算的当前事件。
如果模式 A 是在模式 B 之前定义的,则 A 无法引用 B,则只能按顺序访问定义的模式。
允许
...
DEFINE
A AS Last(A.value),
B AS Max(A.value) + Max(B.value),
...
不允许
...
DEFINE
A AS Last(A.value) + Last(B.Value),
B AS Max(A.value) + Max(B.value),
...
聚合方法
以下聚合方法可用于 MEASURES 和 DEFINE:
- Min – 到目前为止聚合的最小数字。
- Max – 到目前为止聚合的最大数字。
- First - 聚合的第一个值。
- Last – 到目前为止聚合的最后一个值。
示例:
加注高压油箱是一个危险的过程,需要密切监视,因为油箱上的压力增加也会提高其温度,压力需要稳步增加,以给储罐冷却的时间,同时补充填充。
在此示例中,开发人员希望在高压罐开始增加压力时监视其加注情况。 油箱开始加注,不能在不到 3 分钟内将压力增加一倍,否则油箱过热,并可能导致灾难性故障。
以下查询可用于监视进度:
SELECT *
INTO output FROM input TIMESTAMP BY time
MATCH_RECOGNIZE (
LIMIT DURATION (minute, 3)
MEASURES
MAX(Dangerous.pressure) as pressure,
Classifier() as patterns
AFTER MATCH SKIP TO NEXT ROW
PATTERN (Normal+ Dangerous+)
DEFINE
Normal AS Normal.isFilling = 1,
Dangerous AS Max(Dangerous.pressure) > 2* Max(Normal.pressure)
) AS T
此查询将 Normal 与填充油箱的任何事件匹配,如果压力在 3 分钟内超过 正常 填充的两倍,则事件以 危险 模式的最大压力读数触发。
限制
只能将字段值用于聚合。 聚合调用内不能调用任何函数。
允许
... DEFINE A AS Max(A.value) > 5, ...
不允许
... DEFINE A AS Max(udf.myUdf(A.value)) > 5, ...
只能将单个字段作为输入参数提供给聚合函数。
允许
... DEFINE A AS Max(A.value) > 5, ...
不允许
... DEFINE A AS Max(A.value1 + A.value2) > 5, ...