过滤向量搜索策略:在 Azure AI 搜索中对向量查询应用过滤器
在 Azure AI 搜索中,过滤向量搜索将向量相似度与元数据过滤相结合。预过滤在评分前缩小候选集,可降低延迟但可能损失召回率;后过滤保留召回但可能返回的文档少于 k。必须同时测试两种模式,以找到适合数据的最佳平衡。
本文内容
简明答案
在 Azure AI 搜索中,过滤向量搜索允许在向量查询上附加过滤表达式。过滤针对的是索引中的非向量元数据字段,而不是向量字段本身。引擎可以在向量相似度评分之前或之后应用过滤。预过滤会在最近邻搜索之前缩小候选文档集合,这可能会悄然丢弃满足向量相似度但不符合元数据条件的相关文档,但对于选择性强的过滤器可以降低延迟。后过滤则先在整个索引上计算相似度,然后再剔除不匹配的结果,这可能导致返回的文档数量少于请求的 k。选择哪种方式是策略决策:文档建议在使用语义排序器时倾向于后过滤,因为它需要更大的候选池,但仍需对两种模式进行测试以确定最适合自己的数据。实现时,需要在向量字段旁设计可过滤的文本或数值字段,并在查询请求中设置 vectorFilterMode 参数。
在 Azure AI 搜索中,过滤向量搜索的含义
过滤向量搜索指在包含向量查询的请求中附加过滤表达式。过滤仅作用于索引模式中的文本或数值字段,永远不针对向量字段本身。这使得在执行嵌入的最近邻相似度搜索时,能够基于元数据条件包含或排除文档。引擎可以在向量查询执行前或后处理过滤,从而改变进入相似度评分管道的文档集合。
实用建议
预过滤在 kNN 评分前先缩小候选集,可在过滤高度选择性时降低延迟。但它可能悄然丢弃概念上相关的文档,文档建议使用代表性查询对预过滤和后过滤模式进行基准测试,以确认在特定数据分布下的权衡。
预过滤与后过滤:核心决策
搜索引擎可以在执行向量查询之前或之后应用过滤。这是一种策略决策,而非语法选择,直接影响候选池的大小。预过滤先运行过滤,减少向量搜索需要评分的文档集合;后过滤则在整个索引上执行向量搜索,随后剔除不匹配的结果。此选择会影响召回率、精确度以及返回的文档数量。文档并未规定唯一最佳模式,而是建议对两者进行测试,以确定哪种更适合特定场景。
设计可过滤的元数据字段
由于向量字段不可过滤,所有希望在查询时约束的属性必须存储在单独的、在索引模式中标记为 filterable 的非向量字段中。例如,要按类别、位置或日期过滤,需要为这些属性创建文本或数值字段,并将其 filterable 属性设为 true。查询中的过滤表达式引用这些字段,而不是向量字段。没有这些字段,过滤向量搜索无法实现。这一步是查询使用过滤器的前提条件,必须在任何向量搜索之前完成。
vectorFilterMode 参数及具体查询示例
混合搜索文档提供了一个具体查询示例,演示了过滤向量搜索的实际使用。请求中使用 geo.distance 过滤表达式查找距离某点 300 公里以内的酒店,并将 vectorFilterMode 设置为 postFilter。查询还包含全文搜索、两个针对不同向量字段的向量查询、分面以及语义排序。过滤表达式为 geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300,vectorFilterMode 为 postFilter。这意味着引擎首先在所有酒店中找到 50 个最近邻,然后剔除超出半径的文档,结果集可能少于 50 条。向量查询指定 k=50 并使用 oversampling 提升召回率。示例展示了过滤、向量查询和其他功能在单个请求中的共存方式。
POST https://{{searchServiceName}}.search.windows.net/indexes/hotels-vector-quickstart/docs/search?api-version=2026-04-01
content-type: application/JSON
{
"count": true,
"search": "historic hotel walk to restaurants and shopping",
"select": "HotelId, HotelName, Category, Description, Address/City, Address/StateProvince",
"filter": "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",
"vectorFilterMode": "postFilter",
"facets": ["Address/StateProvince"],
"vectorQueries": [
{
"kind": "vector",
"vector": [<array of embeddings>],
"k": 50,
"fields": "DescriptionVector",
"exhaustive": true,
"oversampling": 20
},
{
"kind": "vector",
"vector": [<array of embeddings>],
"k": 50,
"fields": "Description_frVector",
"exhaustive": false,
"oversampling": 10
}
],
"skip": 0,
"top": 10,
"queryType": "semantic",
"queryLanguage": "en-us",
"semanticConfiguration": "my-semantic-config"
}与语义排序器的交互
在使用语义排序器时,文档建议以后过滤作为起点。原因在于语义排序器需要更大的候选池来读取并重新排序。预过滤可能会过度缩小池子,限制排序器的效果。不过,这并非硬性规则;源文档明确建议进行测试,以确认哪种行为对查询更佳。语义排序器在全文搜索和向量搜索的合并结果上工作,过滤可以在合并前或合并后应用,进而影响输入到排序器的集合。如果在使用语义排序器时将向量查询的 k 设置为 50,可最大化可供重新排序的输入数量。
权衡:预过滤下的召回损失
预过滤在计算向量相似度之前缩小候选集合。这可能会悄然丢弃那些在元数据条件上不符合但在向量空间中与查询向量非常相似的文档。例如,一家完美匹配语义的酒店若稍微超出地理半径,则会在评分前被排除。后过滤则在完整索引上计算相似度,然后剔除不匹配的结果,可能返回的文档少于 k,但确保相似度排名考虑了所有文档。选择预过滤还是后过滤本质上是召回率、结果数量和延迟之间的权衡。预过滤保留 k 并可能降低延迟,但风险是遗漏相关文档;后过滤保留召回率,却可能返回更少的结果并需要更多计算。
将过滤器与分面和评分配置结合使用
过滤器和分面针对的是索引中与全文搜索倒排索引和向量索引不同的数据结构。当过滤器和分面操作执行时,搜索引擎可以将这些操作的结果应用到混合搜索的响应中。这意味着过滤器可以与分面导航和评分配置共存,而不会与向量排名冲突。分面是在过滤后对最终结果集进行计算。评分配置可以应用于文本字段,但显式的 orderby 会覆盖相似度和 BM25 相关性排序,因此若希望相似度和 BM25 驱动排名,应避免使用 orderby。
适用范围限制及重新考虑方案的时机
主要限制在于向量字段本身不可过滤,所有过滤条件必须存在于单独的非向量字段中。后过滤可能返回的文档数量少于请求的 k,这需要在应用层进行处理。预过滤可以降低延迟,但可能降低召回率。文档建议对两种模式进行测试,而不是假设唯一正确答案。如果过滤条件高度选择性且需要精确的 k 结果,可能需要调整 oversampling 或重新设计过滤方式。测试应包括在真实工作负载下测量召回率、精确度和延迟。如果无论过滤模式或 oversampling 设置都无法得到满意结果,需考虑将约束移入向量嵌入本身,采用元数据感知的嵌入策略,或放宽过滤条件。
检查清单
- 确认查询中的每个过滤条件对应索引模式中标记为 filterable 的非向量字段。
- 确保在混合查询请求中将 vectorFilterMode 参数设置为 preFilter 或 postFilter。
- 使用代表性查询对预过滤和后过滤模式进行基准测试,以确定在特定数据集上的召回率、延迟和结果数量的最佳平衡。
- 检查后过滤模式下返回的文档可能少于请求的 k,并在应用逻辑中进行相应处理。
- 确保在混合结果集上应用分面和评分配置,并且它们不会干扰向量排名。
适用范围
向量字段本身不能用于过滤表达式;每个过滤条件必须在单独的非向量字段中定义。后过滤可能返回的文档数量少于请求的 k,因为相似度先在完整索引上计算,然后再剔除不匹配的结果。预过滤会在最近邻搜索前缩小候选池,可能导致召回率下降,尽管对高度选择性的过滤器可降低延迟。文档建议对两种模式进行测试,以确定最适合数据分布和查询模式的方案。