Поиск по диапазону с использованием StructArray
Используйте эту страницу для выполнения поиска по диапазону в подполях вектора StructArray. Поиск по диапазону возвращает векторные совпадения, оценка или расстояние которых находится в пределах указанного диапазона. Для полей StructArray используйте поиск по диапазону с векторным поиском на уровне элементов, при котором каждый элемент Struct просматривается независимо.
На этой странице используется коллекция « tech_articles » из раздела «Создание поля StructArray». В коллекции имеется поле StructArray с именем « chunks ». Подполе вектора « chunks[emb] » индексировано для поиска на уровне элементов с использованием стандартной векторной метрики, такой как « COSINE », « IP » или « L2 ».
Как поиск по диапазону применяется к StructArray
| Режим поиска | Поведение поиска по диапазону | Детализация результатов |
|---|---|---|
| Поиск по EmbeddingList | Не поддерживается. | Не применимо. |
| Поиск на уровне элементов | Используйте обычный векторный запрос с параметром « radius » и, при необходимости, « range_filter ». | Уровень элементов структуры. |
| Гибридный поиск | Поддерживается, если запрос StructArray направлен на векторное поле на уровне элементов. Запросы на уровне EmbeddingList не поддерживают поиск по диапазону. | Поиск на уровне элементов, затем гибридное переранжирование. |
Если вам нужны только ближайшие элементы Struct, начните с базового векторного поиска с StructArray. Используйте поиск по диапазону, когда результат должен удовлетворять ограничению по оценке или расстоянию, а не только ранжированию по топ-K.
Прежде чем начать
Перед запуском поиска по диапазону подготовьте коллекцию, данные и индексы.
| Требования | Подробности |
|---|---|
| Поле StructArray | Коллекция содержит поле StructArray, например chunks. |
| Подполе вектора на уровне элементов | Целевым подполем вектора является chunks[emb], а не chunks[emb_list_vector]. |
| Метрика индексации | Векторное подполе индексируется с помощью обычной векторной метрики, например COSINE, IP или L2. |
| Данные запроса | Запрос представляет собой обычный вектор, а не EmbeddingList. |
Информацию о настройке индекса см. в разделе «Индексирование полей StructArray».
Используйте параметры radius и range_filter
Установите значение radius, чтобы определить границу поиска. Установите значение range_filter, если вам также требуется внутренняя граница. Выбор направления зависит от того, что является более предпочтительным: меньшее расстояние или более высокий показатель схожести.
| Тип метрики | Чем выше оценка, тем лучше? | Условие диапазона при использовании параметра « range_filter » |
|---|---|---|
L2 | Нет. Лучше меньшее расстояние. | range_filter <= distance < radius |
IP, COSINE | Да. Чем выше оценка, тем лучше. | radius < distance <= range_filter |
Если задано только значение « radius », поиск по диапазону возвращает результаты, удовлетворяющие внешней границе метрики. Выбирайте значения в соответствии со шкалой оценок или расстояний ваших вложений.
Выполнение поиска по диапазону на уровне элементов
В следующем примере выполняется поиск отдельных фрагментов, векторы « chunks[emb] » которых достаточно схожи с вектором запроса. Каждое совпадение представляет собой соответствующий элемент Struct.
from pymilvus import MilvusClient
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus",
)
query_vector = [0.19, 0.24, 0.30, 0.37]
results = client.search(
collection_name="tech_articles",
data=[query_vector],
anns_field="chunks[emb]",
search_params={
"params": {
"radius": 0.80,
"range_filter": 0.95,
},
},
limit=10,
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
"chunks[page]",
"chunks[quality_score]",
],
)
for hits in results:
for hit in hits:
print(
"doc_id:", hit["id"],
"distance:", hit["distance"],
"offset:", hit.get("offset"),
"entity:", hit["entity"],
)
В данном примере COSINE является метрикой типа «похожесть», поэтому диапазон результатов больше, чем radius, и меньше или равен range_filter. Значение offset идентифицирует совпадающий элемент Struct в массиве chunks при возвращении результата.
Добавление скалярных фильтров
Вы можете комбинировать поиск по диапазону на уровне элементов со скалярной фильтрацией StructArray. Используйте предикат верхнего уровня для полей родительского объекта и element_filter, чтобы ограничить, какие элементы Struct участвуют в векторном поиске по диапазону.
filter_expr = (
'category == "search" && '
'element_filter(chunks, '
'$[section] == "index" && '
'$[quality_score] > 0.9)'
)
results = client.search(
collection_name="tech_articles",
data=[query_vector],
anns_field="chunks[emb]",
search_params={
"params": {
"radius": 0.80,
"range_filter": 0.95,
},
},
filter=filter_expr,
limit=10,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
Предикат верхнего уровня выбирает сущности-кандидаты. Предикат ` element_filter ` ограничивает векторный поиск по диапазону только соответствующими элементами Struct. Дополнительные примеры фильтрации см. в разделе «Фильтрованный поиск с использованием StructArray».
Использование поиска по диапазону в гибридном поиске
Векторные поля на уровне элементов StructArray поддерживают поиск по диапазону в гибридном поиске. Добавьте radius и, при необходимости, range_filter в запрос AnnSearchRequest, нацеленный на векторное поле на уровне элементов StructArray.
from pymilvus import AnnSearchRequest, RRFRanker
title_req = AnnSearchRequest(
data=[query_vector],
anns_field="title_vector",
limit=10,
)
chunk_req = AnnSearchRequest(
data=[query_vector],
anns_field="chunks[emb]",
param={
"params": {
"radius": 0.80,
"range_filter": 0.95,
},
},
limit=10,
expr='element_filter(chunks, $[section] == "index")',
)
results = client.hybrid_search(
collection_name="tech_articles",
reqs=[title_req, chunk_req],
ranker=RRFRanker(),
limit=5,
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
В данном примере только подзапрос chunks[emb] использует параметры поиска по диапазону. Запрос StructArray по-прежнему следует семантике на уровне элементов: границы диапазона применяются к совпадениям элементов Struct до того, как гибридный поиск объединит и переранжирует результаты.
Интерпретация результатов поиска по диапазону
| Элемент результата | Значение |
|---|---|
id | Первичный ключ сущности, содержащей найденный элемент Struct. |
distance или оценка | Оценка или расстояние между вектором запроса и вектором сопоставленного элемента Struct. |
offset | Позиция найденного элемента Struct в поле StructArray (с нулевой базой) при возвращении. |
| Повторяющиеся первичные ключи | Возможны. В указанный диапазон может попадать более одного элемента Struct в одной и той же сущности. |
limit | Применимо к совпадениям элементов, а не к уникальным родительским сущностям. |
Ограничения
Не используйте запрос «
EmbeddingList» или метрику «MAX_SIM*» для поиска по диапазону в подполях вектора StructArray. Поиск на уровне EmbeddingList не поддерживает поиск по диапазону.Не сочетайте поиск по диапазону с поиском по группировке. Если вам требуется по одному результату на родительскую сущность, запустите поиск на уровне элементов без параметров диапазона и используйте группировку там, где она поддерживается.
Гибридный поиск по диапазону поддерживается для векторных полей StructArray на уровне элементов. Он не поддерживается для запросов StructArray на уровне EmbeddingList.
Распространенные ошибки
Выполнение поиска по диапазону по метрике «
chunks[emb_list_vector]», которая предназначена для поиска на уровне EmbeddingList.Использование запроса «
MAX_SIM_COSINE» вместо обычной метрики, такой как «COSINE», для поиска по диапазону на уровне элементов.Использование запроса
EmbeddingListвместо обычного векторного запроса.Предположение, что результаты поиска по диапазону будут уникальными для родительского объекта. Поиск по диапазону возвращает совпадающие элементы структуры.
Использование
chunks.embвместо требуемого синтаксиса пути к подполюchunks[emb].
Следующие шаги
Чтобы ознакомиться с двумя основными режимами векторного поиска StructArray, прочтите раздел «Базовый векторный поиск с StructArray».
Чтобы добавить скалярные фильтры к поиску по диапазону, ознакомьтесь со статьёй «Фильтрованный поиск с StructArray».
Чтобы возвращать не более одного результата на родительский объект там, где это поддерживается, ознакомьтесь со статьёй «Групповой поиск с StructArray».
Чтобы ознакомиться с ограничениями поиска для конкретных версий, ознакомьтесь с разделом «Ограничения StructArray».