Выполнение поиска похожих векторов

В данном разделе рассматривается, как использовать Milvus для поиска сущностей.

В Milvus поиск похожих векторов вычисляет расстояние между вектором запроса и векторами в коллекции (с использованием указанной меры сходства) и возвращает наиболее похожие результаты. Вы можете выполнить смешанный поиск, указав булевское выражение для фильтрации скалярных или первичных ключевых полей.

В следующем примере показано, как выполнить поиск похожих векторов в наборе данных, содержащем 2000 строк данных, включая идентификатор книги (первичный ключ), количество слов (скалярное поле) и аннотацию книги (векторное поле), для моделирования поиска конкретных книг на основе их векторизованных описаний. Milvus вернет наиболее похожие результаты на основе вектора запроса и заданных параметров поиска.

Загрузка Коллекции

Все операции поиска и запроса в Milvus выполняются в памяти. Перед выполнением поиска похожих векторов загрузите коллекцию в память.

from pymilvus import Collection
collection = Collection("book")      # Получить существующую коллекцию
collection.load()

Подготовка Параметров Поиска

Подготовьте соответствующие параметры для вашего сценария поиска. В следующем примере определяются параметры, которые поиск будет использовать для вычисления расстояния с использованием евклидова расстояния и получения векторов из десяти ближайших кластеров, построенных индексом IVF_FLAT.

search_params = {
    "metric_type": "L2",
    "offset": 5,
    "ignore_growing": False,
    "params": {"nprobe": 10}
}
Параметр Описание
metric_type Метод, используемый для измерения расстояния между векторами во время поиска. Он должен быть таким же, как метод, указанный во время построения индекса. См. меры сходства для получения дополнительной информации.
offset Количество сущностей для пропуска во время поиска. Сумма этого значения и limit метода search должна быть меньше 16384. Например, если вы хотите запросить 9-е и 10-е ближайшие соседей к вектору запроса, установите limit на 2 и offset на 8.
ignore_growing Игнорировать ли растущие сегменты во время поиска похожих сущностей. Значение по умолчанию - False, указывает, что поиск включает растущие сегменты.
params Параметры поиска, специфичные для указанного типа индекса. См. векторный индекс для получения дополнительной информации. Возможные варианты включают: - nprobe указывает количество кластерных единиц для поиска. Этот параметр доступен только при установке index_type в IVF_FLAT, IVF_SQ8 или IVF_PQ. Значение должно быть меньше значения nlist, указанного во время построения индекса. - ef указывает диапазон поиска. Этот параметр доступен только при установке index_type в HNSW. Значение должно быть между top_k и 32768. - radius указывает угол, где находятся векторы с наименьшим сходством. - range_filter указывает фильтр, используемый для фильтрации значений векторного поля, чье сходство с вектором запроса попадает в определенный диапазон.

Выполнение поиска векторов

Используйте Milvus для поиска векторов. Чтобы выполнить поиск в определенном разделе, укажите список имен разделов.

Milvus поддерживает установку уровня последовательности для поиска. В этом примере устанавливается уровень последовательности "Strong". Вы также можете установить уровень последовательности "Bounded", "Session" или "Eventually". Для получения дополнительной информации о четырех уровнях последовательности в Milvus см. Последовательность.

results = collection.search(
    data=[[0.1, 0.2]], 
    anns_field="book_intro", 
    param=search_params,
    limit=10,
    expr=None,
    output_fields=['title'],
    consistency_level="Strong"
)

results[0].ids

results[0].distances

hit = results[0][0]
hit.entity.get('title')
Параметр Описание
data Векторы, используемые для поиска.
anns_field Название поля для поиска.
param Параметры поиска, специфичные для индекса. Дополнительную информацию см. в индексе векторов.
limit Количество возвращаемых результатов. Это значение, плюс offset в param, должно быть меньше 16 384.
expr Логическое выражение для фильтрации свойств. Дополнительную информацию см. в Правилах логических выражений.
output_fields (опционально) Названия полей для возврата. Поля векторов в настоящее время не поддерживаются.
consistency_level (опционально) Уровень последовательности для поиска.

Проверьте значения первичного ключа и расстояний до самых похожих векторов.

results[0].ids
results[0].distances

После завершения поиска освободите загруженную коллекцию в Milvus, чтобы уменьшить потребление памяти.

collection.release()

Ограничения

Функция Максимальный предел
Длина названия коллекции 255 символов
Количество разделов в коллекции 4 096
Количество полей в коллекции 256
Количество фрагментов в коллекции 256
Размер вектора 32 768
Top K 16 384
Входные векторы 16 384

Выполнение смешанного поиска

Смешанный поиск по сути является поиском векторов с фильтрацией атрибутов. Указав логическое выражение, используемое для фильтрации скалярных полей или полей первичных ключей, поиск может быть ограничен под определенными условиями.

В следующем примере показано, как выполнять смешанный поиск на основе обычного векторного поиска. Предположим, вы хотите найти определенные книги на основе векторизованных резюме, но хотите выполнять поиск только в пределах определенного диапазона количества слов. Затем вы можете указать логическое выражение в параметрах поиска для фильтрации поля word_count. Milvus будет выполнять поиск только по подобным векторам в сущностях, которые соответствуют выражению.

Указав логическое выражение, вы можете фильтровать скалярные поля сущностей во время векторного поиска. В следующем примере ограничивается область поиска векторов в указанном диапазоне значений word_count.

Вы также можете использовать динамические поля в выражении фильтрации и использовать выходные поля в запросе поиска. Например, обратитесь к динамическому шаблону.

search_param = {
  "data": [[0.1, 0.2]],
  "anns_field": "book_intro",
  "param": {"metric_type": "L2", "params": {"nprobe": 10}, "offset": 0},
  "limit": 10,
  "expr": "word_count <= 11000",
}
res = collection.search(**search_param)

Проверьте возвращенные результаты.

assert len(res) == 1
hits = res[0]
assert len(hits) == 2
print(f"- Общее количество совпадений: {len(hits)}, идентификаторы совпадений: {hits.ids} ")
print(f"- Идентификатор лучшего совпадения: {hits[0].id}, расстояние: {hits[0].distance}, оценка: {hits[0].score} ")

Выполнение поиска диапазона

Поиск диапазона - это метод фильтрации результатов поиска на основе расстояния между вектором запроса и значениями векторного поля. Для измерения расстояния можно использовать различные метрики расстояния.

При выполнении поиска диапазона Milvus сначала выполняет поиск похожих векторов, а затем выполняет фильтрацию векторов на основе указанных условий расстояния и возвращает векторы, расстояние до которых попадает в определенный диапазон.

В следующем примере показано, как выполнить поиск диапазона на основе обычного векторного поиска.

Загрузка коллекции

Все операции поиска и запросов в Milvus выполняются в памяти. Перед выполнением поиска похожих векторов коллекцию необходимо загрузить в память.

from pymilvus import Collection
collection = Collection("book")      # Получите существующую коллекцию
collection.load()

Настройка фильтрации векторов по диапазону

В сравнении с обычным поиском векторов, в Milvus контроль за диапазонным поиском осуществляется путем введения двух новых параметров, radius и range_filter, для получения желаемых результатов поиска в определенном диапазоне.

Параметр radius определяет минимальный угол, при котором векторы считаются похожими. Опциональный параметр range_filter может использоваться вместе с radius для фильтрации значений векторного поля на основе сходства с запросов в определенном диапазоне. Оба параметра radius и range_filter имеют тип данных FLOAT. Установка этих двух параметров эффективно балансирует точность и эффективность поиска.

Обычно сходство измеряется расстоянием между значением векторного поля и запросом вектора. Выбор различных метрик расстояния оказывает значительное влияние на конфигурацию radius и range_filter.

Например, в случае расстояния L2, результаты поиска должны быть отфильтрованы на основе значений векторного поля с расстоянием меньше, чем radius. Это связано с тем, что в расстоянии L2 меньшие расстояния указывают на большее сходство. Исходя из этого, если вы хотите отфильтровать некоторые из самых похожих векторов, вы можете указать эффективное значение range_filter, которое меньше, чем radius.

search_params = {
    "metric_type": "L2",
    "params": {
        "radius": 10.0,
        "range_filter" : 5.0
    }
}

В случае расстояния IP сценарий иной. С расстоянием IP большее расстояние указывает на большее сходство. Следовательно, в отличие от расстояния L2, значения radius и range_filter при расстоянии IP являются противоположными. Другими словами, при использовании range_filter для фильтрации некоторых из самых похожих векторов на основе расстояния IP, эффективное значение range_filter должно быть больше, чем radius, и расстояние полученных векторов должно быть больше, чем radius, но меньше или равно range_filter.

search_params = {
    "metric_type": "IP",
    "params": {
        "radius": 0.8,
        "range_filter" : 1.0
    }
}

Осуществление диапазонного поиска

Путем указания radius и range_filter на основе типа измерения расстояния, вы можете определить диапазон векторов, которые будут возвращены.

Осуществите диапазонный поиск по сходству в пределах диапазона от 5.0 до 10.0 на базе расстояния L2:

search_param = {
  "data": [[0.1, 0.2]], # Вектор запроса
  "anns_field": "book_intro", # Поле для поиска
  "param": { "metric_type": "L2", "params": { "nprobe": 10, "radius": 10.0, "range_filter" : 5.0 }, "offset": 0 },
  "limit": 2,
  "output_fields": ["int64", "float"]  # Возвращаемые поля
}

res = collection.search(**search_param)

Осуществите диапазонный поиск по сходству в пределах диапазона от 1.0 до 0.8 на базе расстояния IP:

search_param = {
  "data": [[0.1, 0.2]], # Вектор запроса
  "anns_field": "book_intro", # Поле для поиска
  "param": {"metric_type": "IP", "params": { "nprobe": 10, "radius": 0.8, "range_filter" : 1.0 }, "offset": 0 },
  "limit": 2,
  "output_fields": ["int64", "float"]  # Возвращаемые поля
}

res = collection.search(**search_param)

Итог

В Milvus диапазонный поиск позволяет получить векторные результаты, которые подходят в указанный диапазон расстояний. Эта функциональность активируется путем указания radius и range_filter в параметрах поиска. В таблице ниже суммируется конфигурация этих двух параметров для различных типов измерения расстояния.

Тип измерения расстояния Конфигурация
L2 и другие расстояния range_filter <= distance < radius
Расстояние IP и косинусное расстояние radius < distance <= range_filter