ビットセットがベクトル類似検索の多用途性を可能にする理由
ビットセット表紙画像
Milvus2.0のリリースに伴い、ベクトルデータベースに不可欠な様々な新機能が提供される。新機能のうち、タイムトラベル、属性フィルタリング、削除操作は、ビットセットという共通のメカニズムによって実現されるため、相関関係がある。
そこで本稿では、Milvusにおけるビットセットの概念を明らかにし、削除操作、タイムトラベル、属性フィルタリングをサポートするビットセットの仕組みを3つの例を用いて説明する。
ビットセットとは?
ビットセットとは、ビット番号("0 "と "1")の配列のことで、特定のデータ情報を表現するために使用することができます。ビットセットを使用すると、Intsやfloat、charsで保存するのとは対照的に、特定のタイプのデータをコンパクトかつ効率的に保存することができます。ビットセットはブーリアンロジックで動作し、出力の値は有効か無効かのどちらかで、通常はそれぞれ "1 "と "0 "で表されます。「1」は有効を表し、「0」は無効を表す。ビットセットは非常に効率的でストレージを節約できるため、属性フィルタリング、削除操作、タイムトラベルなど、多くの機能を実現するためにも使用できる。
バージョン0.7.0から、Milvusでは削除機能を実現するためにビットセットという概念が導入されました。具体的には、セグメント内の各行が削除されたかどうかをマークするためにビットセットが使用されます。削除されたエンティティは対応するビットセットで "1 "とマークされ、その結果、削除されたエンティティは検索やクエリの際に計算されない。
Milvus 2.0バージョンでは、属性フィルタリングやタイムトラベルなど、より多くの機能を実現するためにビットセットの適用が拡張された。ビットセットにおける一般的な原則は変わらない。つまり、あるエンティティが対応するビットセットで "1 "とマークされている場合、検索やクエリの際にそのエンティティは無視される。ビットセットはmilvusの3つの機能を有効にするために使用されます:
- 属性フィルタリング
- データ削除
- タイムトラベル
Milvusでビットセットはどのように機能するのか?
以下はMilvusにおけるビットセットの動作を説明するための例です。
前提条件
8つのエンティティを持つセグメントがあり、一連のデータ操作言語(DML)イベントが下図の順序で発生したとする。
primary_keys
がそれぞれ[1, 2, 3, 4]であるエンティティのうち4つは、タイムスタンプts
が100に等しいときに挿入される。- 残りの4つのエンティティは、
primary_keys
が[5, 6, 7, 8]であり、タイムスタンプts
が200になったときに挿入される。 primary_keys
が[7, 8]であるエンティティは、タイムスタンプts
が300になったときに削除される。primary_keys
が [1, 3, 5, 7] であるエンティティだけが、属性フィルタリングの条件を満たす。
DMLイベント
ケース1
ユーザがtime_travel
に設定した値が 150 であったとする。つまり、ts
= 150のとき、ユーザはMilvusに格納されているデータに対して問い合わせを行う。ビットセット生成プロセスを図1に示す。
最初のフィルタリング段階では、エンティティ[1, 3, 5, 7]は有効なフィルタリング結果であり、ビットセット内で "1 "とマークされているため、filter_bitset
の結果は[1, 0, 1, 0, 1, 0, 1, 0]となるはずである。しかし、エンティティ[4,5,6,7]は、ts
が150に等しいとき、 ベクトルデータベースに挿入さえされていない。したがって、これら4つのエンティ ティは、フィルタリング条件に関係なく「0」とマークされるべきである。これで、ビットセットの結果は[1, 0, 1, 0, 0, 0, 0]となるはずである。Milvusでは、ビットセットで "1 "とマークされたエンティティは検索中やクエリ中に無視されるというのがビットセット計算の一般原則であるため、削除ビットマップと組み合わせるためには、タイムトラベルと属性フィルタリング後のビットセット結果を反転させる必要がある。filter_bitset
の反転結果は、[0, 1, 0, 1, 1, 1, 1]でなければならない。
削除ビットセットdel_bitset
の初期値は [0, 0, 0, 0, 0, 1, 1] である。しかし、エンティティ7と8はts
が300になるまで削除されない。したがって、ts
が150 のとき、エンティティ7と8はまだ有効である。その結果、タイムトラベル後のdel_bitset
の値は[0, 0, 0, 0, 0, 0, 0]となる。
タイムトラベルと属性フィルタリングの結果、2つのビットセットができた: filter_bitset
[0, 1, 0, 1, 1, 1, 1, 1]とdel_bitset
[0, 0, 0, 0, 0, 0, 0, 0]である。 この2つのビットセットを "OR "二進論理演算子で結合する。最終的なresult_bitset
の値は[0, 1, 0, 1, 1, 1, 1]となる。つまり、次の検索またはクエリーの段階では、エンティティ1と3のみが計算される。
図1
ケース2
ユーザがtime_travel
に設定した値が 250 であるとする。つまり、ts
= 250のとき、ユーザはMilvusに格納されているデータに対してクエリを実行する。ビットセット生成プロセスを図2に示す。
ケース1と同様に、最初の属性フィルタリング段階の結果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, 1, 1]となるはずである。しかし、エンティティ7と8はts
が300になるまで削除されなかった。したがって、ts
が250 のとき、エンティティ7と8はまだ有効である。その結果、タイムトラベル後のdel_bitset
の値は[0, 0, 0, 0, 0, 0, 0]となる。
タイムトラベルと属性フィルタリングの結果、2つのビットセットができた: filter_bitset
[0, 1, 0, 1, 0, 1, 0, 1] とdel_bitset
[0, 0, 0, 0, 0, 0, 0] である。 この2つのビットセットを "OR "二進論理演算子で結合する。result_bitset
の最終的な値は [0, 1, 0, 1, 0, 1, 0, 1] である。つまり、[1, 3, 5, 7]のエンティティのみが、次の検索またはクエリーの段階で計算される。
図2
ケース3
ユーザがtime_travel
に設定した値が350であるとする。つまり、ts
= 350のとき、ユーザはMilvusに格納されているデータに対してクエリを実行する。ビットセット生成プロセスは図3のようになる。
ケース1および2と同様に、最初の属性フィルタリング段階の結果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]となり、ケース2と同じである。
削除ビットセットdel_bitset
については、ts
=350の時点ですでにエンティティ7と8が削除されているため、del_bitset
の結果は[0, 0, 0, 0, 0, 1, 1]となるはずである。
タイムトラベルと属性フィルタリングの結果、2つのビットセットができた: filter_bitset
[0, 1, 0, 1, 0, 1, 0, 1, 1]とdel_bitset
[0, 0, 0, 0, 0, 1, 1]である。 この2つのビットセットを "OR "二進論理演算子で結合する。result_bitset
の最終的な値は [0, 1, 0, 1, 0, 1, 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