Pattern Matching
在 agentic search 应用中,Vector Search 和 grep 风格的 Pattern Matching 通常相互补充。Vector Search 检索语义相关的 Entity,而 Pattern Matching 则通过精确的字符串结构进一步缩小结果范围,例如错误码、日志前缀、电子邮件域名、URL 路径或标识符。
在 Milvus 中,你可以在标量 Filter 中使用 LIKE 表达这些 Pattern 约束以执行简单的通配符匹配,并使用 =~ 或 !~ 表达 RE2 正则表达式。你可以将这些 Filter 与 query、search 或 Hybrid Search 结合使用。
本页介绍 query、search 和 Hybrid Search 使用的标量 Filter 表达式中的 Pattern Matching。这些表达式会评估字段值,不会改变 Analyzer 生成的 Token。如需在文本分析期间过滤 Token,请参阅 Regex Analyzer Filter。
Pattern Matching 表达式写在 filter 参数中。例如,以下查询会匹配包含 E1001 等错误码的日志消息:
from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530")
res = client.query(
collection_name="log_events",
filter='message =~ "E[0-9]{4}"',
output_fields=["message", "severity"],
)
本页示例重点展示赋给 filter 的表达式。你可以在接受标量 Filter 的 Milvus 操作中使用相同的 Filter 表达式语法,例如 query、search 和 Hybrid Search。
Supported field types
Pattern matching 适用于字符串值。
| 目标 | LIKE | Regex =~ / !~ | 说明 |
|---|---|---|---|
VARCHAR 字段 | 是 | 是 | 对字符串字段执行 pattern matching 的典型目标。 |
JSON path with VARCHAR cast type | 是 | 是 | 要获得正向匹配,JSON path 的值必须是字符串。如果你为 JSON path 创建索引以加速查询,请设置 json_cast_type="varchar"。 |
ARRAY<VARCHAR> 元素 | 是 | 是 | 可按索引匹配特定元素,例如 tags[0]。Pattern matching 不会扫描所有元素;它只作用于指定索引处的元素。 |
Numeric、Boolean、vector、TEXT 或其他非 VARCHAR 目标 | 否 | 否 | Pattern matching 仅适用于 VARCHAR 值、解析为字符串的 JSON path,或已索引的 ARRAY<VARCHAR> 元素。 |
Choose LIKE or regex
选择能够表达所需模式的最简单运算符。
如果你需要精确字符串匹配,建议使用 ==,而不是模式匹配。仅当 filter 需要匹配某种模式时,才使用 LIKE 或 regex。
| 要求 | 推荐运算符 | 示例 | 说明 |
|---|---|---|---|
| 精确字符串相等 | == | status == "active" | 精确匹配字符串 active。 |
| 简单前缀匹配 | LIKE | name LIKE "Prod%" | 匹配以 Prod 开头的字符串。 |
| 简单后缀匹配 | LIKE | filename LIKE "%.json" | 匹配以 .json 结尾的字符串。 |
| 简单包含匹配 | LIKE | description LIKE "%vector database%" | 匹配字符串中任意位置包含 vector database 的值。 |
| 匹配结构化代码或固定长度模式 | =~ | code =~ "E[0-9]{4}" | 匹配包含 E 后跟四位数字的字符串(区分大小写),例如 E1001。 |
| 不区分大小写的模式匹配 | =~ 与 (?i) | message =~ "(?i)error" | 匹配 error、ERROR 或其他大小写变体。 |
| 排除匹配 regex 模式的值 | !~ | message !~ "^DEBUG" | 排除以 DEBUG 开头的字符串。 |
使用 LIKE 进行简单通配符匹配。当模式需要字符类、重复、error|failed 等 alternation、锚点或不区分大小写匹配时,使用 regex。
Use LIKE
LIKE 运算符用于对字符串值进行简单的通配符匹配。它仅支持以下通配符:
| 通配符 | 描述 |
|---|---|
% | 匹配零个或多个字符。 |
_ | 精确匹配一个字符。 |
常见 LIKE 模式
通过 % 和 _ 的位置控制固定文本在匹配字符串中的出现位置。
| 需求 | 模式 | Filter 示例 |
|---|---|---|
| 以指定前缀开头 | Prod% | filter = 'name LIKE "Prod%"' |
| 以指定后缀结尾 | %.json | filter = 'filename LIKE "%.json"' |
| 包含指定子串 | %vector% | filter = 'description LIKE "%vector%"' |
| 在固定位置匹配一个字符 | AB_% | filter = 'code LIKE "AB_%"' |
LIKE matching behavior
使用 LIKE 进行前缀、后缀、包含以及固定位置的单字符匹配。LIKE 不支持字符类(例如 [0-9])、alternation(例如 error|failed)、重复次数(例如 {4})、锚点(例如 ^ 或 $),也不支持大小写不敏感标志(例如 (?i))。如需这些模式,请使用 regex。
使用 == 进行完整字符串的精确相等匹配。仅当 filter 需要通配符匹配时才使用 LIKE。
Escaping wildcards in a LIKE pattern
在 LIKE pattern 中,% 匹配零个或多个字符,_ 匹配恰好一个字符。要按字面量匹配 %、_ 或 \,请使用反斜杠 (\) 转义该字符:
name LIKE r"\%"匹配字面值%。name LIKE r"\_%"匹配以字面量_开头的值。name LIKE r"\\%"匹配以字面量反斜杠开头的值。
Raw string literal(原始字符串字面量)写作 r"..." 或 r'...',会在 Milvus filter expression 中按原样保留反斜杠。对于包含反斜杠的 LIKE 和 regex pattern,建议使用 Raw string literal。如果不使用 Raw string,普通字符串字面量仍会先处理转义序列,然后再对 pattern 求值,因此可能需要更多反斜杠。
Use regex | Milvus 3.0.x
当 pattern 需要字符类、重复、或、锚点或不区分大小写匹配等正则表达式功能时,请使用 regex filter。Milvus 会将 RE2 正则表达式应用于字符串值。
=~ 或 !~ 的右侧必须是字符串字面量。
| Operator | 含义 | 示例 |
|---|---|---|
=~ | 匹配满足 regex pattern 的值。 | filter = 'message =~ "E[0-9]{4}"' |
!~ | 排除满足 regex pattern 的值。 | filter = 'message !~ "^DEBUG"' |
Use raw string literals
对于包含反斜杠的 regex pattern,建议使用 raw string literals。在 raw string 中,写作 r"..." 或 r'...',反斜杠会原样传递给 regex engine。这样可以避免 ordinary string literals 所需的额外转义。
例如:
filter = 'message =~ r"\d{4}-\d{2}-\d{2}"'
这会匹配包含类似 2026-07-01 的日期值的字符串。
如果不使用 raw string,ordinary string literals 会先处理转义序列,然后才评估 regex pattern,因此 \d、\s 或转义后的字面字符等 pattern 可能需要额外的反斜杠。
Common regex patterns
以下示例在 Milvus filter 表达式中使用常见 RE2 语法。若需完整的 regex 语法,请参阅 RE2 syntax 参考。
| 需求 | Pattern | Filter 示例 |
|---|---|---|
| 包含字面文本 | error | filter = 'message =~ "error"' |
| 以前缀开头 | ^ERR | filter = 'code =~ "^ERR"' |
| 以后缀结尾 | \.json$ | filter = 'filename =~ "\\.json$"' |
| 匹配数字序列 | [0-9]+ | filter = 'message =~ "[0-9]+"' |
| 匹配固定数量的数字 | [0-9]{4} | filter = 'code =~ "[0-9]{4}"' |
| 匹配邮箱域名 | @example\.com$ | filter = 'email =~ "@example\\.com$"' |
| 不区分大小写匹配 | (?i)error | filter = 'message =~ "(?i)error"' |
| 匹配完整字符串 | ^prod-[0-9]+$ | filter = 'name =~ "^prod-[0-9]+$"' |
要匹配多个单词中的任意一个,请使用带 | 的 alternation:
filter = 'message =~ "error|failed|timeout"'
按字面值匹配 regex 元字符时,需要在 regex pattern 中转义这些字符。例如,要匹配字面点号(regex 中为 \.),请在 Python filter 字符串中写作 \\.:
filter = 'email =~ "@gmail\\.com$"'
注意:Milvus regex filter 遵循 RE2 语法。如果 regex pattern 使用了 RE2 不支持的语法,或 pattern 本身无效,Milvus 会拒绝该 filter 表达式。有关 regex 元字符、flag 和匹配行为的详细信息,请参阅 RE2 syntax 参考。
Matching behavior
子字符串匹配
Milvus regex 匹配采用子字符串语义。pattern 不需要匹配整个字段值。例如,以下 filter 同时匹配 E1001 和 failed with E1001 after retry:
filter = 'message =~ "E[0-9]{4}"'
如需匹配整个字段值,请使用 ^ 和 $ 锚点:
# Match only values that are exactly E followed by four digits
filter = 'code =~ "^E[0-9]{4}$"'
可为 NULL 的 VARCHAR 字段
Regex filter 不会匹配 NULL 值。这同时适用于 =~ 和 !~。如果你希望排除某个 regex pattern 但保留 NULL 值,请显式添加 OR field IS NULL:
filter = 'message !~ "^DEBUG" OR message IS NULL'
JSON paths
对于 JSON path,当 path 缺失、为 NULL,或解析为非字符串值时,regex filter 的行为不同:
| Filter | 是否包含缺失/NULL/非字符串值? | 说明 |
|---|---|---|
json_field["path"] =~ "pattern" | 否 | 仅匹配满足 regex pattern 的字符串值。 |
json_field["path"] !~ "pattern" | 是 | 返回 path 缺失、为 NULL、非字符串,或为不匹配 regex pattern 的字符串的 Entity。 |
使用索引加速 Pattern Matching
Milvus 支持在 string 字段上使用多种索引类型,这些索引可与 VARCHAR 字段或 JSON string 路径上的 LIKE 和 regex 过滤器配合使用,例如 NGRAM、STL_SORT、INVERTED 和 BITMAP。Pattern matching 即使没有索引也可以工作,但在大型数据集上,索引可以提升性能。
索引效果取决于 pattern 表达式、Milvus 是否能提取固定的字面量子字符串,以及目标字段的基数和分布。前缀类 pattern(例如 name LIKE "Prod%")可能适合与中缀或后缀类 pattern(例如 description LIKE "%vector%" 或 filename LIKE "%.json")不同的索引策略。
你可以将下表作为起点,然后基于自己的 workload 进行 benchmark:
| Pattern 或数据特征 | 可考虑的索引 | 说明 |
|---|---|---|
包含固定字面量子字符串,例如 message =~ "error.*timeout" 或 message LIKE "%database%" | NGRAM | 当 Milvus 能够从 pattern 中提取有意义的字面量子字符串时会有所帮助。详情请参阅 NGRAM。 |
| 前缀、精确或类似相等匹配的 string 过滤器,尤其是低到中等基数字段 | STL_SORT、INVERTED 或 BITMAP | 当字段存在重复值,或过滤条件接近精确匹配时,可能更有效。详情请参阅 STL_SORT、INVERTED 和 BITMAP。 |
| 没有固定字面量的 regex pattern,或主要由字符类、短 token 或通配符组成的 pattern | 在依赖索引加速前先进行 benchmark | 这些 pattern 的索引选择性可能有限,并可能回退到更大范围的扫描。 |