Bitset
本主题介绍了位集机制,它有助于在 Milvus 中实现属性过滤和删除操作等关键功能。
概述
位集是一组位。位是只有两个可能值的元素,最典型的是 0
和 1
,或布尔值 true
和 false
。在 Milvus 中,位集是位数字 0
和 1
的数组,可以用来紧凑高效地表示某些数据,而不是使用整数、浮点数或字符。位数字默认为 0
,只有在满足某些要求时才设置为 1
。
位集上的操作使用布尔逻辑进行,在这种逻辑下,输出值要么有效要么无效,分别用 1
和 0
表示。例如,逻辑运算符 AND
可以用来根据相同索引位置的项目比较两个位集,并产生一个包含结果的新位集。如果一个位置的两个项目相同,则在新位集中该位置写入 1
;如果不同则写入 0
。
实现
位集是一个简单但强大的机制,帮助 Milvus 执行属性过滤、数据删除和时间旅行查询。
属性过滤
由于位集只包含两个可能的值,它们非常适合存储属性过滤的结果。满足给定属性过滤器要求的数据用 1
标记。
数据删除
位集作为一种紧凑的方式来存储 segment 中某行是否被删除的信息。删除的实体在相应的位集中用 1
标记,在搜索或查询期间不会被计算。
示例
这里我们提供三个示例来说明位集在 Milvus 中的使用方式,参考了上面讨论的位集的所有三个主要实现。在所有三种情况下,都有一个包含 8 个实体的 segment,然后按如下所示的顺序发生一系列数据操作语言(DML)事件。
- 四个实体,其
primary_key
分别为 [1, 2, 3, 4],在时间戳ts
等于 100 时插入。 - 其余四个实体,其
primary_key
为 [5, 6, 7, 8],在时间戳ts
等于 200 时插入。 primary_key
为 [7, 8] 的实体在时间戳ts
等于 300 时被删除。- 只有
primary_key
为 [1, 3, 5, 7] 的实体满足属性过滤条件。
情况一
在这种情况下,用户将 time_travel
设置为 150,这意味着用户对满足 ts = 150
的数据进行查询。位集生成过程如图 1 所示。
在初始过滤阶段,filter_bitset
应该是 [1, 0, 1, 0, 1, 0, 1, 0]
,其中实体 [1, 3, 5, 7] 被标记为 1
,因为它们是有效的过滤结果。
但是,实体 [4, 5, 6, 7] 在 ts
等于 150 时尚未插入向量数据库。因此,无论过滤条件如何,这四个实体都应该标记为 0。现在位集结果应该是 [1, 0, 1, 0, 0, 0, 0, 0]
。
如数据删除中所讨论的,标记为 1
的实体在搜索或查询期间被忽略。现在需要翻转位集结果,以便与删除位图结合,这给我们 [0, 1, 0, 1, 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, 1]
和 del_bitset
[0, 0, 0, 0, 0, 0, 0, 0]
。使用 OR
二进制逻辑运算符组合这两个位集。result_bitset 的最终值是 [0, 1, 0, 1, 1, 1, 1, 1]
,意味着只有实体 1 和 3 将在后续的搜索或查询阶段被计算。
情况二
在这种情况下,用户将 time_travel
设置为 250。位集生成过程如图 2 所示。
像情况一一样,初始 filter_bitset
是 [1, 0, 1, 0, 1, 0, 1, 0]
。
当 ts
= 250 时,所有实体都在向量数据库中。因此,当我们考虑时间戳时,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, 0]
。使用 OR
二进制逻辑运算符组合这两个位集。result_bitset 是 [0, 1, 0, 1, 0, 1, 0, 1]
。也就是说,只有实体 [1, 3, 5, 7] 将在后续的搜索或查询阶段被计算。
情况三
在这种情况下,用户将 time_travel
设置为 350。位集生成过程如图 3 所示。
与之前的情况一样,初始 filter_bitset
是 [0, 1, 0, 1, 0, 1, 0, 1]
。
当 ts
= 350 时,所有实体都在向量数据库中。因此,最终翻转的 filter_bitset
是 [0, 1, 0, 1, 0, 1, 0, 1]
,与情况二相同。
至于删除位集 del_bitset
,由于实体 7 和 8 在 ts = 350
时已经被删除,因此,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]
。也就是说,只有实体 [1, 3, 5] 将在后续的搜索或查询阶段被计算。
下一步
现在您了解了位集在 Milvus 中的工作原理,您可能还想:
- 了解如何使用字符串过滤您的搜索结果,或参考我们文档中的混合搜索。
- 了解数据在 Milvus 中的处理方式。