过滤
Weaviate 提供了强大的过滤向量搜索能力,允许您将向量搜索与结构化标量过滤器结合使用。这使您可以找到与查询向量最接近,同时又满足特定条件的向量。
Weaviate 中的过滤向量搜索基于预过滤的概念。这意味着过滤器是在执行向量搜索之前构建的。与某些预过滤实现不同,Weaviate 的预过滤不需要暴力向量搜索,并且效率很高。
从 v1.34 开始,Weaviate 使用 ACORN 过滤器策略作为默认设置。这种过滤方法显著提高了大型数据集的性能,尤其是在过滤器与查询向量的相关性较低时。
后过滤与预过滤
无法使用预过滤的系统通常必须使用后过滤。这是一种先执行向量搜索,然后删除不符合过滤器的结果的方法。这会导致两个主要缺点
- 您无法轻松预测搜索中包含多少元素,因为过滤器应用于已经减少的候选人列表。
- 如果过滤器非常严格,即它只匹配相对于数据集大小的一小部分数据点,则原始向量搜索可能根本不包含任何匹配项。
预过滤克服了后过滤的局限性。预过滤描述了一种在开始向量搜索之前确定合格候选人的方法。向量搜索然后仅考虑存在于“允许”列表中的候选人。
一些作者区分“预过滤”和“单阶段过滤”,前者意味着暴力搜索,后者则不然。我们不进行这种区分,因为即使在预过滤的情况下,Weaviate 也无需诉诸暴力搜索,这归功于其组合倒排索引和 HNSW 索引。
Weaviate 中高效的预过滤搜索
在存储部分,我们详细描述了 Weaviate 中的分片构成。最值得注意的是,每个分片都包含一个倒排索引,紧邻 HNSW 索引。这允许进行高效的预过滤。过程如下
- 使用倒排索引(类似于传统的搜索引擎)创建合格候选人的允许列表。该列表本质上是
uint64id 的列表,因此它可以增长得很大而不会牺牲效率。 - 执行向量搜索,并将允许列表传递给 HNSW 索引。索引将正常地沿着任何节点的边移动,但只会将存在于允许列表中的 id 添加到结果集中。搜索的退出条件与未过滤搜索相同:当达到所需的限制并且额外的候选人不再提高结果质量时,搜索将停止。
过滤器策略
Weaviate 支持两种过滤器策略:sweeping 和 acorn,专门针对 HNSW 索引类型。
ACORN
Weaviate 过滤算法 ACORN 基于论文 ACORN: Performant and Predicate-Agnostic Search Over Vector Embeddings and Structured Data。我们将其称为 ACORN,但 Weaviate 中的实际实现是受该论文启发的自定义实现。(本文档中对 ACORN 的引用是指 Weaviate 实现。)
ACORN 算法旨在通过以下方式加速使用 HNSW 索引 的过滤搜索
- 不符合过滤器的对象在距离计算中被忽略。
- 该算法通过使用多跳方法评估候选人的邻域,更快地到达 HNSW 图的相关部分。
- 额外的入口点与过滤器匹配,随机播种以加速收敛到过滤区域。
当过滤器与查询向量的相关性较低时,ACORN 算法特别有用。换句话说,当过滤器排除图中最类似于查询向量的区域中的许多对象时。
我们的内部测试表明,对于低相关性、严格的过滤器,ACORN 算法可以更快,尤其是在大型数据集上。如果这对您的用例来说是一个瓶颈,我们建议启用 ACORN 算法。
Sweeping
sweeping 策略基于“扫描”HNSW 图的概念。
该算法从根节点开始遍历图,在每个节点评估与查询向量的距离,同时将过滤器的“允许列表”作为上下文。如果未满足过滤器,则跳过该节点并继续遍历。重复此过程,直到达到所需的结果数量。
可以通过在相关 HNSW 向量索引的 集合配置 中设置 filterStrategy 字段来启用 sweeping 算法。
indexFilterable
indexFilterable 索引通过使用 Roaring Bitmaps 加快基于匹配的过滤。Roaring Bitmaps 采用各种策略来提高效率,通过将数据划分为块并对每个块应用适当的存储策略。这实现了高数据压缩和集合操作速度,从而提高了 Weaviate 的过滤速度。
如果您正在处理大型数据集,这可能会显著提高您的过滤性能,因此我们鼓励您迁移并重新索引。
此外,我们的团队会维护我们底层的 Roaring Bitmap 库,以解决任何问题并进行改进。
indexFilterable 用于 text 属性
用于 text 属性的 roaring bitmap 索引使用两个单独的(filterable & searchable)索引实现,取代了现有的单个索引。您可以配置新的 indexFilterable 和 indexSearchable 参数,以确定是否创建 roaring 集合索引和适合 BM25 的 Map 索引。 (默认情况下都已启用。)
要了解有关 Weaviate roaring bitmap 实现的更多信息,请参阅 内联文档。
indexRangeFilters
indexRangeFilters 索引是用于按数值范围过滤的基于范围的索引。此索引适用于 int、number 或 date 属性。该索引不适用于这些数据类型的数组。
在内部,可范围索引实现为 roaring bitmap 切片。此数据结构将索引限制为可以存储为 64 位整数的值。
indexRangeFilters 仅适用于新属性。无法将现有属性转换为使用范围索引。
预过滤搜索的回调
得益于 Weaviate 的自定义 HNSW 实现,该实现坚持遵循 HNSW 图中的所有链接,仅在考虑结果集时应用过滤器条件,因此保持了图的完整性。过滤搜索的回调通常不会比未过滤搜索差。
下图显示了不同限制级别的过滤器。从左(匹配数据集的 100%)到右(匹配数据集的 1%),过滤器变得越来越严格,而不会对 k=10、k=15 和 k=20 向量搜索中的回调产生负面影响。

平面搜索截止
Weaviate 提供了一个选项,可以自动切换到平面(暴力)向量搜索,当过滤器变得过于严格时。此场景仅适用于组合向量和标量搜索。有关为什么 HNSW 需要在某些过滤器上切换到平面搜索的详细说明,请参阅 medium 上的这篇文章。简而言之,如果过滤器非常严格(即,数据集的一小部分被匹配),则 HNSW 遍历会变得详尽。换句话说,过滤器越严格,HNSW 的性能就越接近对整个数据集的暴力搜索。但是,使用如此严格的过滤器,我们已经将数据集缩小到很小的一部分。因此,如果性能几乎是暴力搜索,那么仅在匹配子集上搜索而不是整个数据集会更有效。
下图显示了具有不同严格性的过滤器。从左(0%)到右(100%),过滤器变得越来越严格。截止值配置为数据集大小的 ~15%。这意味着虚线右侧使用暴力搜索。

作为比较,不使用截止值的纯 HNSW,相同的过滤器如下所示

截止值可以配置为 模式中每个集合的 vectorIndexConfig 设置的一部分。
更多资源
问题和反馈
如果您有任何问题或反馈,请在 用户论坛 中告诉我们。
