Как битсет обеспечивает универсальность поиска векторного сходства
Изображение на обложке Bitset
Авторы: Юдонг Цай и Анджела Ни.
Вместе с выпуском Milvus 2.0 появились новые возможности векторной базы данных. Среди новых возможностей - перемещение по времени, фильтрация атрибутов и операции удаления, поскольку эти три функции реализуются с помощью одного общего механизма - битового набора.
Поэтому цель этой статьи - прояснить концепцию битсета в Milvus и объяснить на трех примерах, как он работает для поддержки операций удаления, Time Travel и фильтрации атрибутов.
Что такое битсет?
Набор битов - это массив битовых чисел ("0" и "1"), которые можно использовать для представления определенной информации. С помощью битовых наборов вы можете компактно и эффективно хранить определенные типы данных, в отличие от хранения их в Ints, float или chars. Битовые наборы работают на основе булевой логики, согласно которой значение вывода является либо допустимым, либо недопустимым, обычно обозначаемым "1" и "0" соответственно. "1" означает действительное значение, а "0" - недействительное. Поскольку битовые наборы очень эффективны и позволяют экономить место для хранения, они также могут использоваться для реализации многих функций, таких как фильтрация атрибутов, операции удаления, путешествие во времени и другие.
Начиная с версии 0.7.0, концепция битов была введена в Milvus для реализации функции удаления. Если говорить точнее, bitset используется для того, чтобы отметить, удален ли каждый ряд в сегменте. Удаленные сущности помечаются "1" в соответствующем битовом наборе, и в результате удаленные сущности не будут вычисляться при поиске или запросе.
В версии Milvus 2.0 применение битовых наборов расширено, чтобы включить дополнительные возможности, такие как фильтрация атрибутов и путешествие во времени. Общий принцип работы битового набора остался прежним. То есть если сущность отмечена "1" в соответствующем битовом наборе, она будет игнорироваться при поиске или запросе. Битовые наборы используются для включения трех функций в Milvus:
- фильтрация атрибутов
- удаление данных
- Запрос с перемещением во времени
Как битовые наборы работают в Milvus?
Приведенные ниже примеры иллюстрируют работу битов в Milvus.
Предпосылки
Предположим, что имеется сегмент с восемью сущностями, и серия событий языка манипулирования данными (DML) происходит в порядке, показанном на рисунке ниже.
- Четыре сущности, чьи
primary_keys
равны [1, 2, 3, 4] соответственно, вставляются, когда временная меткаts
равна 100. - Оставшиеся четыре сущности, чьи
primary_keys
равны [5, 6, 7, 8], вставляются, когда временная меткаts
равна 200. - Сущности, чьи
primary_keys
равны [7, 8], удаляются, когда временная меткаts
равна 300. - Условиям фильтрации атрибутов удовлетворяют только сущности, чьи
primary_keys
равны [1, 3, 5, 7].
События DML
Случай первый
Предположим, что значение, которое пользователь устанавливает для time_travel
, равно 150. Другими словами, пользователь выполняет запрос к данным, хранящимся в Milvus, когда ts
= 150. Процесс формирования набора битов показан на рисунке 1.
На этапе начальной фильтрации результат filter_bitset
должен быть [1, 0, 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, 0, 0]. Поскольку в Milvus общий принцип вычисления битовых наборов заключается в том, что сущности, отмеченные в битовом наборе "1", игнорируются во время поиска или запроса, результат битового набора после путешествия во времени и фильтрации атрибутов необходимо перевернуть, чтобы объединить с битовой картой удаления. Перевернутый результат filter_bitset
должен иметь вид [0, 1, 0, 1, 1, 1, 1, 1, 1, 1].
Что касается битового набора удаления del_bitset
, то его начальное значение должно быть [0, 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, 0, 0].
Теперь у нас есть два набора битов после Путешествия во времени и фильтрации атрибутов: filter_bitset
[0, 1, 0, 1, 1, 1, 1, 1, 1] и del_bitset
[0, 0, 0, 0, 0, 0, 0, 0, 0]. Объедините эти два набора битов с помощью оператора двоичной логики "ИЛИ". Конечное значение result_bitset
- [0, 1, 0, 1, 1, 1, 1, 1, 1]. Иными словами, на следующем этапе поиска или запроса будут вычислены только сущности 1 и 3.
Рисунок 1
Случай второй
Предположим, что значение, которое пользователь задает для time_travel
, равно 250. Другими словами, пользователь выполняет запрос к данным, хранящимся в Milvus, когда ts
= 250. Процесс генерации набора битов показан на рисунке 2.
Как и в первом случае, результирующий filter_bitset
начального этапа фильтрации атрибутов должен иметь вид [1, 0, 1, 0, 1, 0, 1, 0].
Все сущности [1, 2, 3, 4, 5, 6, 7, 8] вставляются в базу векторов, когда ts
= 250. Таким образом, предыдущий результат filter_bitset
остается неизменным. Снова нужно перевернуть результат filter_bitset
, и мы получим [0, 1, 0, 1, 0, 1, 0, 1, 0, 1].
Что касается набора битов удаления del_bitset
, то его начальное значение должно быть [0, 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, 0, 0].
Теперь у нас есть два набора битов после Путешествия во времени и фильтрации атрибутов: filter_bitset
[0, 1, 0, 1, 0, 1, 0, 1] и del_bitset
[0, 0, 0, 0, 0, 0, 0, 0]. Объедините эти два набора битов с помощью оператора двоичной логики "ИЛИ". Конечное значение result_bitset
- [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]. То есть на следующем этапе поиска или запроса будут вычислены только сущности [1, 3, 5, 7].
Рисунок 2
Третий случай
Предположим, что значение, которое пользователь задает для time_travel
, равно 350. Другими словами, пользователь выполняет запрос к данным, хранящимся в Milvus, когда ts
= 350. Процесс генерации набора битов показан на рисунке 3.
Как и в первом и втором случае, результирующим filter_bitset
начального этапа фильтрации атрибутов является [0, 1, 0, 1, 0, 1, 0, 1, 0, 1].
Все сущности [1, 2, 3, 4, 5, 6, 7, 8] вставляются в базу векторов при ts
= 350. Таким образом, конечный перевернутый результат filter_bitset
- [0, 1, 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, 0, 1] и del_bitset
[0, 0, 0, 0, 0, 0, 1, 1]. Объедините эти два набора битов с помощью оператора двоичной логики "ИЛИ". Конечное значение result_bitset
- [0, 1, 0, 1, 0, 1, 1, 1, 1]. То есть на следующем этапе поиска или запроса будут вычислены только сущности [1, 3, 5].
Рисунок 3
Что дальше?
В серии блогов о новых функциях версии 2.0 мы постараемся рассказать о дизайне новых функций. Читайте больше в этой серии блогов!
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word