模式匹配

在基于代理的搜索应用中,向量搜索和 grep 风格的模式匹配通常相辅相成。向量搜索可检索语义相关的实体,而模式匹配则通过精确的字符串结构(如错误代码、日志前缀、电子邮件域名、URL 路径或标识符)来缩小搜索结果范围。

在 Milvus 中,您可以在标量过滤器中使用LIKE 进行简单的通配符匹配,或使用=~!~ 进行RE2正则表达式匹配,来表达这些模式约束。您可以将这些过滤器与querysearch 或混合搜索相结合。

本页面介绍了querysearch 以及混合搜索所使用的标量过滤器表达式中的模式匹配。这些表达式对字段值进行评估,但不会更改分析器生成的令牌。若要在文本分析过程中过滤令牌,请参阅“正则表达式分析器过滤器”

模式匹配表达式需编写在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 完全匹配。
简单前缀匹配LIKEname LIKE "Prod%"匹配以Prod 开头的字符串。
简单后缀匹配LIKEfilename LIKE "%.json"匹配以.json 结尾的字符串。
简单包含匹配LIKEdescription LIKE "%vector database%"匹配字符串中任意位置包含vector database 的值。
匹配结构化代码或固定长度模式=~code =~ "E[0-9]{4}"匹配区分大小写且包含E 后跟四位数字的字符串,例如E1001
不区分大小写的模式匹配=~ 使用(?i)message =~ "(?i)error"匹配errorERROR 或其他大小写变体。
排除匹配正则表达式模式的值!~message !~ "^DEBUG"排除以DEBUG 开头的字符串。

使用LIKE 进行简单的通配符匹配。当模式需要字符类、重复、选择(如error|failed )、锚点或不区分大小写的匹配时,请使用正则表达式。

使用 LIKE

LIKE 操作符用于对字符串值进行简单的通配符匹配。它仅支持以下通配符:

通配符说明
%匹配零个或多个字符。
_匹配恰好一个字符。

常见的 LIKE 模式

使用%_ 的位置来控制固定文本在匹配字符串中的出现位置。

要求模式过滤示例
以前缀开头Prod%filter = 'name LIKE "Prod%"'
以后缀结尾%.jsonfilter = '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 语法参考。

要求模式过滤示例
包含字面文本errorfilter = 'message =~ "error"'
以前缀开头^ERRfilter = '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)errorfilter = '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 字符串路径的正则表达式过滤器配合使用,例如NGRAMSTL_SORTINVERTEDBITMAP 。模式匹配可在无索引的情况下进行,但使用索引可提升大型数据集的性能。

索引的有效性取决于模式表达式、Milvus 能否提取固定的字面量子字符串,以及目标字段的基数和分布情况。前缀式模式(如name LIKE "Prod%" )可能受益于与中缀或后缀模式(如description LIKE "%vector%"filename LIKE "%.json" )不同的索引策略。

请将下表作为参考起点,然后根据您自己的工作负载进行基准测试:

模式或数据特征应考虑的索引备注
包含固定的字面量子字符串,例如message =~ "error.*timeout"message LIKE "%database%"NGRAM当 Milvus 能从模式中提取有意义的字面量子字符串时,此项会有所帮助。详情请参阅NGRAM
前缀、精确或等值类型的字符串过滤器,特别适用于基数较低至中等的字段STL_SORTINVERTEDBITMAP当字段包含重复值或过滤条件接近精确匹配时,此方法可能更有效。详情请参阅STL_SORTINVERTEDBITMAP
不包含固定字符的正则表达式模式,或以字符类、短令牌或通配符为主的模式在依赖索引加速之前请先进行基准测试这些模式可能提供的索引选择性有限,并可能退化为更广泛的扫描。

翻译自DeepL

想要更快、更简单、更好用的 Milvus SaaS服务 ?

Zilliz Cloud是基于Milvus的全托管向量数据库,拥有更高性能,更易扩展,以及卓越性价比

免费试用 Zilliz Cloud
反馈

此页对您是否有帮助?