模式匹配
在基于代理的搜索应用中,向量搜索和 grep 风格的模式匹配通常相辅相成。向量搜索可检索语义相关的实体,而模式匹配则通过精确的字符串结构(如错误代码、日志前缀、电子邮件域名、URL 路径或标识符)来缩小搜索结果范围。
在 Milvus 中,您可以在标量过滤器中使用LIKE 进行简单的通配符匹配,或使用=~ 或!~ 进行RE2正则表达式匹配,来表达这些模式约束。您可以将这些过滤器与query 、search 或混合搜索相结合。
本页面介绍了query 、search 以及混合搜索所使用的标量过滤器表达式中的模式匹配。这些表达式对字段值进行评估,但不会更改分析器生成的令牌。若要在文本分析过程中过滤令牌,请参阅“正则表达式分析器过滤器”。
模式匹配表达式需编写在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` 的表达式。您可以在接受标量过滤器的 Milvus 操作中使用相同的过滤表达式语法,例如 `query`、`search` 和混合搜索。
支持的字段类型
模式匹配适用于字符串值。
| 目标 | LIKE | 正则表达式=~ /!~ | 注释 |
|---|---|---|---|
VARCHAR 字段 | 是 | 是 | 字符串字段模式匹配的典型目标。 |
JSON 路径,使用VARCHAR 类型转换 | 是 | 是 | JSON 路径值必须为字符串才能进行正向匹配。若要在 JSON 路径上创建索引以提高性能,请设置 `json_cast_type="varchar"`。 |
ARRAY<VARCHAR> 元素 | 是 | 是 | 按索引匹配特定元素,例如tags[0] 。模式匹配不会扫描所有元素;它仅适用于指定索引处的元素。 |
数值、布尔值、向量、TEXT 或其他非VARCHAR 目标 | 否 | 否 | 模式匹配仅适用于VARCHAR 值、解析为字符串的JSON路径,或带索引的ARRAY<VARCHAR> 元素。 |
选择 LIKE 或 regex
请选择能表达所需模式的最简单操作符。
如果您需要精确的字符串匹配,建议使用== 而非模式匹配。仅当筛选条件需要匹配特定模式时,才使用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 或其他大小写变体。 |
| 排除匹配正则表达式模式的值 | !~ | message !~ "^DEBUG" | 排除以DEBUG 开头的字符串。 |
使用LIKE 进行简单的通配符匹配。当模式需要字符类、重复、选择(如error|failed )、锚点或不区分大小写的匹配时,请使用正则表达式。
使用 LIKE
LIKE 操作符用于对字符串值进行简单的通配符匹配。它仅支持以下通配符:
| 通配符 | 说明 |
|---|---|
% | 匹配零个或多个字符。 |
_ | 匹配恰好一个字符。 |
常见的 LIKE 模式
使用% 和_ 的位置来控制固定文本在匹配字符串中的出现位置。
| 要求 | 模式 | 过滤示例 |
|---|---|---|
| 以前缀开头 | Prod% | filter = 'name LIKE "Prod%"' |
| 以后缀结尾 | %.json | filter = 'filename LIKE "%.json"' |
| 包含子字符串 | %vector% | filter = 'description LIKE "%vector%"' |
| 匹配固定位置上的一个字符 | AB_% | filter = 'code LIKE "AB_%"' |
LIKE 匹配行为
使用LIKE 进行前缀、后缀、包含以及固定位置单字符匹配。LIKE 不支持字符类(如[0-9] )、选择关系(如error|failed )、重复计数(如{4} )、锚点(如^ 或$ )以及不区分大小写的标志(如(?i) )。对于此类模式,请使用正则表达式。
使用== 进行精确的全字符串相等比较。仅当过滤器需要通配符匹配时,才使用LIKE 。
在 LIKE 模式中转义通配符
在LIKE 模式中,% 匹配零个或多个字符,而_ 匹配恰好一个字符。若要精确匹配% 、_ 或\ 这些字符串,请使用反斜杠 (\) 对字符进行转义:
name LIKE r"\%"匹配字面值%。name LIKE r"\_%"匹配以字面量_开头的值。name LIKE r"\\%"匹配以字面量反斜杠开头的值。
原始字符串字面量(写法为r"..." 或r'...' )在 Milvus 过滤器表达式中会原样保留反斜杠。建议在包含反斜杠的LIKE 和正则表达式模式中使用它们。如果不使用原始字符串,普通字符串字面量在评估模式之前仍会处理转义序列,因此可能需要添加更多反斜杠。
使用正则表达式Compatible with Milvus 3.0.x
当模式需要正则表达式功能(如字符类、重复、选择、锚点或不区分大小写的匹配)时,请使用正则表达式过滤器。Milvus 会对字符串值应用RE2正则表达式。
=~ 或!~ 的右侧必须为字符串字面量。
| 操作符 | 含义 | 示例 |
|---|---|---|
=~ | 匹配满足正则表达式模式的值。 | filter = 'message =~ "E[0-9]{4}"' |
!~ | 排除满足正则表达式模式的值。 | filter = 'message !~ "^DEBUG"' |
使用原始字符串字面量
对于包含反斜杠的正则表达式模式,建议使用原始字符串字面量。在原始字符串中(写法为r"..." 或r'...' ),反斜杠会原样传递给正则表达式引擎。这避免了普通字符串字面量所需的额外转义操作。
例如:
filter = 'message =~ r"\d{4}-\d{2}-\d{2}"'
这将匹配包含类似日期的字符串,例如2026-07-01 。
如果不使用原始字符串,普通字符串字面量会在评估正则表达式模式之前处理转义序列,因此诸如\d 、\s 或包含转义字符的字面量可能需要添加额外的反斜杠。
常见的正则表达式模式
以下示例在 Milvus 过滤器表达式中使用了常见的 RE2 语法。有关完整的正则表达式语法,请参阅RE2 语法参考。
| 要求 | 模式 | 过滤示例 |
|---|---|---|
| 包含字面文本 | 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]+$"' |
若要匹配多个单词中的任意一个,请使用| 进行选择:
filter = 'message =~ "error|failed|timeout"'
当需要匹配正则表达式元字符的字面值时,请在正则表达式模式中对其进行转义。例如,要匹配字面上的点(正则表达式中的 `\. `),请在 Python 过滤器字符串中写为 `\\. `:
filter = 'email =~ "@gmail\\.com$"'
注意:Milvus 正则表达式过滤器遵循 RE2 语法。如果正则表达式模式使用了 RE2 不支持的语法,或者存在其他无效情况,Milvus 将拒绝该过滤器表达式。有关正则表达式元字符、标志和匹配行为的详细信息,请参阅RE2 语法参考。
匹配行为
子字符串匹配
Milvus 的正则表达式匹配采用子字符串语义。模式无需与整个字段值完全匹配。例如,以下过滤器既匹配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}$"'
可为空的 VARCHAR 字段
正则表达式过滤器不会匹配空值。这适用于=~ 和!~ 两种情况。若要排除某个正则表达式模式但保留空值,请显式添加OR field IS NULL :
filter = 'message !~ "^DEBUG" OR message IS NULL'
JSON 路径
对于 JSON 路径,当路径缺失、为空或解析为非字符串值时,正则表达式过滤器的行为会有所不同:
| 过滤器 | 是否包含缺失/null/非字符串值? | 备注 |
|---|---|---|
json_field["path"] =~ "pattern" | 否 | 仅匹配满足正则表达式模式的字符串值。 |
json_field["path"] !~ "pattern" | 是 | 返回路径缺失、为空、非字符串,或字符串不匹配正则表达式模式的实体。 |
利用索引加速模式匹配
Milvus 支持多种字符串字段索引类型,可与LIKE 以及针对VARCHAR 字段或 JSON 字符串路径的正则表达式过滤器配合使用,例如NGRAM 、STL_SORT 、INVERTED 和BITMAP 。模式匹配可在无索引的情况下进行,但使用索引可提升大型数据集的性能。
索引的有效性取决于模式表达式、Milvus 能否提取固定的字面量子字符串,以及目标字段的基数和分布情况。前缀式模式(如name LIKE "Prod%" )可能受益于与中缀或后缀模式(如description LIKE "%vector%" 或filename LIKE "%.json" )不同的索引策略。
请将下表作为参考起点,然后根据您自己的工作负载进行基准测试:
| 模式或数据特征 | 应考虑的索引 | 备注 |
|---|---|---|
包含固定的字面量子字符串,例如message =~ "error.*timeout" 或message LIKE "%database%" | NGRAM | 当 Milvus 能从模式中提取有意义的字面量子字符串时,此项会有所帮助。详情请参阅NGRAM。 |
| 前缀、精确或等值类型的字符串过滤器,特别适用于基数较低至中等的字段 | STL_SORT、INVERTED 或BITMAP | 当字段包含重复值或过滤条件接近精确匹配时,此方法可能更有效。详情请参阅STL_SORT、INVERTED 和BITMAP。 |
| 不包含固定字符的正则表达式模式,或以字符类、短令牌或通配符为主的模式 | 在依赖索引加速之前请先进行基准测试 | 这些模式可能提供的索引选择性有限,并可能退化为更广泛的扫描。 |