字符串运算符
Kusto 查询语言 (KQL) 提供了多种查询运算符用于搜索字符串数据类型。 以下文章介绍如何为字符串词语编制索引、列出字符串查询运算符,以及提供用于优化性能的提示。
了解字符串词语
Kusto 将为所有列(包括 string
类型的列)编制索引。 将根据实际数据为这些列构建多个索引。 这些索引不会直接公开,而是在查询中使用,此类查询的 string
运算符在其名称中包含 has
(如 has
、!has
、hasprefix
、!hasprefix
)。 这些运算符的语义由列的编码方式决定。 这些运算符对词语进行匹配,而不是执行“纯”子字符串匹配。
什么是词语?
默认情况下,每个 string
值都分解为字母数字字符的最大序列,并将这些序列中的每一个都转换为一个词语。
例如,在下面的 string
中,词语是 Kusto
、KustoExplorerQueryRun
以及以下子字符串:ad67d136
、c1db
、4f9f
、88ef
、d94f3b6b0b5a
。
Kusto: ad67d136-c1db-4f9f-88ef-d94f3b6b0b5a;KustoExplorerQueryRun
Kusto 会生成一个词语索引,该词语索引中包含的所有词语均为三个或以上字符,并且由 has
、!has
之类的字符串运算符使用。 如果查询查找少于三个字符的词语,或者使用 contains
运算符,则该查询将恢复为扫描列中的值。 扫描的速度要比在词语索引中查找词语慢得多。
注意
在 EngineV2 中,一个词语由四个或以上字符组成。
针对字符串的运算符
本文中使用了以下缩写词:
- RHS = 表达式的右侧
- LHS = 表达式的左侧
带有 _cs
后缀的运算符要区分大小写。
运算符 | 描述 | 区分大小写 | 示例(生成 true ) |
---|---|---|---|
== |
等于 | 是 | "aBc" == "aBc" |
!= |
不等于 | 是 | "abc" != "ABC" |
=~ |
等于 | 否 | "abc" =~ "ABC" |
!~ |
不等于 | 否 | "aBc" !~ "xyz" |
contains |
RHS 以 LHS 子序列的形式存在 | 否 | "FabriKam" contains "BRik" |
!contains |
LHS 中未出现 RHS | 否 | "Fabrikam" !contains "xyz" |
contains_cs |
RHS 以 LHS 子序列的形式存在 | 是 | "FabriKam" contains_cs "Kam" |
!contains_cs |
LHS 中未出现 RHS | 是 | "Fabrikam" !contains_cs "Kam" |
endswith |
RHS 是 LHS 的闭合子序列 | 否 | "Fabrikam" endswith "Kam" |
!endswith |
RHS 不是 LHS 的闭合子序列 | 否 | "Fabrikam" !endswith "brik" |
endswith_cs |
RHS 是 LHS 的闭合子序列 | 是 | "Fabrikam" endswith_cs "kam" |
!endswith_cs |
RHS 不是 LHS 的闭合子序列 | 是 | "Fabrikam" !endswith_cs "brik" |
has |
右侧 (RHS) 是左侧 (LHS) 的整体 | 否 | "North America" has "america" |
!has |
RHS 不是 LHS 中的完整词语 | 否 | "North America" !has "amer" |
has_all |
与 has 相同,但适用于所有元素 |
否 | "North and South America" has_all("south", "north") |
has_any |
与 has 相同,但适用于任何元素 |
否 | "North America" has_any("south", "north") |
has_cs |
RHS 是 LHS 中的完整词语 | 是 | "North America" has_cs "America" |
!has_cs |
RHS 不是 LHS 中的完整词语 | 是 | "North America" !has_cs "amer" |
hasprefix |
RHS 是 LHS 中的词语前缀 | 否 | "North America" hasprefix "ame" |
!hasprefix |
RHS 不是 LHS 中的词语前缀 | 否 | "North America" !hasprefix "mer" |
hasprefix_cs |
RHS 是 LHS 中的词语前缀 | 是 | "North America" hasprefix_cs "Ame" |
!hasprefix_cs |
RHS 不是 LHS 中的词语前缀 | 是 | "North America" !hasprefix_cs "CA" |
hassuffix |
RHS 是 LHS 中的词语后缀 | 否 | "North America" hassuffix "ica" |
!hassuffix |
RHS 不是 LHS 中的词语后缀 | 否 | "North America" !hassuffix "americ" |
hassuffix_cs |
RHS 是 LHS 中的词语后缀 | 是 | "North America" hassuffix_cs "ica" |
!hassuffix_cs |
RHS 不是 LHS 中的词语后缀 | 是 | "North America" !hassuffix_cs "icA" |
in |
等于任何元素 | 是 | "abc" in ("123", "345", "abc") |
!in |
不等于任何元素 | 是 | "bca" !in ("123", "345", "abc") |
in~ |
等于任何元素 | 否 | "Abc" in~ ("123", "345", "abc") |
!in~ |
不等于任何元素 | 否 | "bCa" !in~ ("123", "345", "ABC") |
matches regex |
LHS 包含 RHS 的匹配项 | 是 | "Fabrikam" matches regex "b.*k" |
startswith |
RHS 是 LHS 的初始子序列 | 否 | "Fabrikam" startswith "fab" |
!startswith |
RHS 不是 LHS 的初始子序列 | 否 | "Fabrikam" !startswith "kam" |
startswith_cs |
RHS 是 LHS 的初始子序列 | 是 | "Fabrikam" startswith_cs "Fab" |
!startswith_cs |
RHS 不是 LHS 的初始子序列 | 是 | "Fabrikam" !startswith_cs "fab" |
性能提示
为了获得更好的性能,当存在两个执行相同任务的运算符时,请使用区分大小写的那个运算符。 例如:
- 使用
==
,而不是=~
- 使用
in
,而不是in~
- 使用
hassuffix_cs
,而不是hassuffix
为了更快地得到结果,如果要测试是否存在符号或字母数字式字词(受非字母数字字符或字段的开头或结尾限制),请使用 has
或 in
。
has
执行起来比 contains
、startswith
或 endswith
更快。
若要搜索 IPv4 地址或其前缀,请对 IPv4 地址使用某个特殊运算符,这些运算符已针对此目的进行了优化。
有关详细信息,请参阅查询最佳做法。
例如,下面的第一个查询运行速度更快:
StormEvents | where State has "North" | count;
StormEvents | where State contains "nor" | count
IPv4 地址的运算符
下面这组运算符提供针对 IPv4 地址或其前缀的索引加速搜索。
运算符 | 说明 | 示例(生成 true ) |
---|---|---|
has_ipv4 | LHS 包含由 RHS 表示的 IPv4 地址 | has_ipv4("Source address is 10.1.2.3:1234", "10.1.2.3") |
has_ipv4_prefix | LHS 包含与 RHS 表示的前缀相匹配的 IPv4 地址 | has_ipv4_prefix("Source address is 10.1.2.3:1234", "10.1.2.") |
has_any_ipv4 | LHS 包含由 RHS 提供的 IPv4 地址之一 | has_any_ipv4("Source address is 10.1.2.3:1234", dynamic(["10.1.2.3", "127.0.0.1"])) |
has_any_ipv4_prefix | LHS 包含与 RHS 提供的前缀之一相匹配的 IPv4 地址 | has_any_ipv4_prefix("Source address is 10.1.2.3:1234", dynamic(["10.1.2.", "127.0.0."])) |