Bitset 如何实现向量相似性搜索的多功能性
Bitset 封面图片
随着 Milvus 2.0 的发布,矢量数据库的各种新的基本功能也一并推出。在这些新功能中,时间旅行、属性过滤和删除操作是相关联的,因为这三个功能是通过一个共同的机制--比特集--来实现的。
因此,本文旨在阐明 Milvus 中比特集的概念,并通过三个例子解释它是如何支持删除操作、时间旅行和属性过滤的。
什么是比特集?
比特集是由比特数("0 "和 "1")组成的数组,可用来表示某些数据信息。与用 Ints、floats 或 chars 存储数据相比,使用比特集可以紧凑、高效地存储某些类型的数据。比特集基于布尔逻辑工作,根据布尔逻辑,输出值要么有效要么无效,通常分别用 "1 "和 "0 "表示。1 "代表有效,"0 "代表无效。由于比特集具有很高的效率,可以节省存储空间,因此还可以用来实现属性过滤、删除操作、时间旅行等多种功能。
从 0.7.0 版开始,为了实现删除功能,Milvus 引入了 bitset 的概念。更具体地说,比特集用于标记段中的每一行是否被删除。已删除的实体在相应的比特集中标记为 "1",因此在搜索或查询时将不会计算已删除的实体。
在 Milvus 2.0 版本中,比特集的应用得到了扩展,可以实现更多的功能,如属性过滤和时间旅行。比特集的一般原则保持不变。也就是说,如果一个实体在相应的比特集中被标记为 "1",那么在搜索或查询时该实体将被忽略。在 Milvus 中,比特集用于实现 3 个功能:
- 属性过滤
- 数据删除
- 时间旅行查询
比特集在 Milvus 中是如何工作的?
下面的示例用于说明比特集在 Milvus 中的工作原理。
前提条件
假设有一个包含八个实体的段,一系列数据操作语言(DML)事件按下图所示顺序发生。
- 其中四个实体(其
primary_keys
分别为 [1、2、3、4])在时间戳ts
等于 100 时被插入。 - 其余四个实体(其
primary_keys
分别为 [5、6、7、8])在时间戳ts
等于 200 时插入。 - 当时间戳
ts
等于 300 时,删除primary_keys
为 [7, 8] 的实体。 - 只有
primary_keys
为 [1, 3, 5, 7] 的实体才满足属性筛选条件。
DML 事件
案例一
假设用户为time_travel
设置的值是 150。换句话说,当ts
= 150 时,用户对存储在 Milvus 中的数据进行查询。比特集生成过程如图 1 所示。
在初始过滤阶段,filter_bitset
的结果应该是[1, 0, 1, 0, 1, 0, 1, 0],因为实体[1, 3, 5, 7]是有效的过滤结果,并在比特集中标记为 "1"。然而,当ts
等于 150 时,实体 [4, 5, 6, 7] 甚至没有被插入向量数据库。因此,无论过滤条件如何,这四个实体都应标记为 "0"。现在比特集的结果应该是 [1, 0, 1, 0, 0, 0, 0, 0]。由于在 Milvus 中,比特集计算的一般原则是在搜索或查询过程中忽略比特集中标记为 "1 "的实体,因此时间旅行和属性过滤后的比特集结果需要翻转,以便与删除比特图相结合。filter_bitset
的翻转结果应为 [0,1,0,1,1,1,1]。
至于删除位图del_bitset
,初始值应为 [0, 0, 0, 0, 0, 0, 1, 1]。但是,实体 7 和实体 8 在ts
为 300 时才会删除。因此,当ts
为 150 时,实体 7 和 8 仍然有效。因此,时间旅行后的del_bitset
值应该是 [0,0,0,0,0,0,0,0]。
现在,经过时间旅行和属性过滤后,我们有了两个比特集: filter_bitset
[0,1,0,1,1,1,1] 和del_bitset
[0,0,0,0,0,0,0]。 用二进制逻辑操作符 "OR "组合这两个比特集。result_bitset
的最终值是 [0,1,0,1,1,1,1]。也就是说,在接下来的搜索或查询阶段,将只计算实体 1 和实体 3。
图 1
案例二
假设用户为time_travel
设置的值是 250。换句话说,当ts
= 250 时,用户对存储在 Milvus 中的数据进行查询。比特集生成过程如图 2 所示。
与第一种情况一样,初始属性过滤阶段的结果filter_bitset
应该是[1, 0, 1, 0, 1, 0, 1, 0]。
当ts
= 250 时,所有实体 [1, 2, 3, 4, 5, 6, 7, 8] 都被插入到向量数据库中。因此,之前filter_bitset
的结果保持不变。同样,我们需要翻转filter_bitset
的结果,就会得到 [0, 1, 0, 1, 0, 1, 0, 1]。
至于删除比特集del_bitset
,初始值应该是 [0, 0, 0, 0, 0, 0, 1, 1]。但是,实体 7 和实体 8 在ts
为 300 时才被删除。因此,当ts
为 250 时,实体 7 和 8 仍然有效。因此,时间旅行后的del_bitset
值应该是 [0,0,0,0,0,0,0,0]。
现在,经过时间旅行和属性过滤后,我们有了两个比特集: filter_bitset
[0,1,0,1,0,1,0,1] 和del_bitset
[0,0,0,0,0,0,0]。 用二进制逻辑操作符 "OR "组合这两个比特集。result_bitset
的最终值是 [0,1,0,1,0,1,0,1]。也就是说,在接下来的搜索或查询阶段,将只计算实体 [1, 3, 5, 7]。
图 2
案例三
假设用户为time_travel
设置的值是 350。换句话说,当ts
= 350 时,用户对存储在 Milvus 中的数据进行查询。比特集生成过程如图 3 所示。
与情况一和情况二相同,初始属性过滤阶段的结果filter_bitset
是 [0, 1, 0, 1, 0, 1, 0, 1]。
当ts
= 350 时,所有实体 [1, 2, 3, 4, 5, 6, 7, 8] 都被插入到向量数据库中。因此,filter_bitset
的最终翻转结果是 [0,1,0,1,0,1,0,1],与情况二相同。
至于删除比特集del_bitset
,由于ts
= 350 时实体 7 和 8 已被删除,因此del_bitset
的结果应该是 [0, 0, 0, 0, 0, 0, 1, 1]。
现在,经过时间旅行和属性过滤后,我们有了两个比特集: filter_bitset
[0, 1, 0, 1, 0, 1, 0, 1] 和del_bitset
[0, 0, 0, 0, 0, 0, 1, 1]。 用二进制逻辑操作符 "OR "组合这两个比特集。result_bitset
的最终值是 [0,1,0,1,0,1,1]。也就是说,在接下来的搜索或查询阶段,将只计算实体 [1, 3, 5]。
图 3
下一步是什么?
在 2.0 新功能系列博客中,我们将介绍新功能的设计。阅读本系列博客的更多内容!
- 什么是比特集?
- 比特集在 Milvus 中是如何工作的?
- 下一步是什么?
On This Page
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word