比特集
本主題介紹在 Milvus 中幫助實現屬性過濾和刪除操作等關鍵功能的 bitset 機制。
概述
比特集是一組比特。比特是只有兩個可能值的元素,最典型的是0
和1
,或者是布林值true
和false
。在 Milvus 中,比特集是由比特數0
和1
組成的陣列,相對於 ints、floats 或 chars,比特集可用來精簡、有效地表示某些資料。位元數預設為0
,只有在符合特定要求時才會被設定為1
。
位元集的運算以布林邏輯進行,在布林邏輯下,輸出值為有效或無效,也分別以1
和0
表示。例如,邏輯運算符 AND
可用於比較兩個位元集,比較的基礎是位於相同索引位置的項目,並將結果產生一個新的位元集。如果某個位置上的兩個項目相同,那麼在新的位元集中1
將被寫入該位置;如果兩個項目不同,則0
。
實作
Bitset 是一個簡單但功能強大的機制,可以幫助 Milvus 執行屬性過濾、資料刪除,以及使用 Time Travel 進行查詢。
屬性過濾
由於 bitset 只包含兩個可能的值,因此非常適合儲存屬性篩選的結果。符合特定屬性篩選條件的資料會以1
標示。
資料刪除
比特集是儲存段中某一行是否被刪除資訊的簡潔方式。已刪除的實體在對應的位元集中會以1
標記,在搜尋或查詢時不會被計算。
範例
在這裡,我們提出三個範例來說明如何在 Milvus 中使用 bitset,並參考上面討論過的所有三種主要 bitset 實作。在所有三個案例中,都有一個包含 8 個實體的區段,接下來會發生一系列的資料處理語言 (DML) 事件,其順序如下所示。
- 其中四個實體,其
primary_key
s 分別為 [1、2、3、4],會在時間戳ts
等於 100 時插入。 - 其餘四個實體,其
primary_key
s 為 [5、6、7、8],會在時間戳ts
等於 200 時插入。 primary_key
s 為 [7, 8] 的實體,會在時間戳記ts
等於 300 時刪除。- 只有
primary_key
s 為 [1, 3, 5, 7] 的實體才滿足屬性過濾的條件。
DML 事件的順序
情況一
在這種情況下,使用者設定time_travel
為 150,這表示使用者對滿足ts = 150
的資料進行查詢。比特集生成過程如圖 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]
。
正如在資料刪除中所討論的,在搜尋或查詢時,標記為1
的實體會被忽略。比特集結果現在需要翻轉,以便與刪除比特圖結合,這樣我們就可以得到[0, 1, 0, 1, 1, 1, 1, 1]
。
至於刪除位元集del_bitset
,初始值應該是[0, 0, 0, 0, 0, 0, 1, 1]
。但是,直到ts
為 300 時,才會刪除實體 7 和 8。因此,當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 會被計算出來。
圖 1.時間旅行 = 150 的搜尋。
案例二
在這種情況下,使用者設定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]
。然而,直到ts
為 300 時,實體 7 和 8 才被刪除。因此,當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
二元邏輯運算符號合併這兩個位元集。結果_比特集是[0, 1, 0, 1, 0, 1, 0, 1]
。也就是說,在接下來的搜尋或查詢階段,只有 Entites [1, 3, 5, 7] 會被計算出來。
圖 2.時間旅行 = 250 的搜尋。
情況三
在這種情況下,使用者設定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] 會被計算出來。
圖 3.時間旅行 = 350 的搜尋。
下一步
現在您知道 bitsets 在 Milvus 中是如何運作的了,您也許還想
- 學習如何使用字串來篩選您的搜尋結果,或參考我們文件上的Hybrid Search。
- 瞭解 Milvus如何處理資料。