Поиск по диапазону с использованием 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].

Следующие шаги

  1. Чтобы ознакомиться с двумя основными режимами векторного поиска StructArray, прочтите раздел «Базовый векторный поиск с StructArray».

  2. Чтобы добавить скалярные фильтры к поиску по диапазону, ознакомьтесь со статьёй «Фильтрованный поиск с StructArray».

  3. Чтобы возвращать не более одного результата на родительский объект там, где это поддерживается, ознакомьтесь со статьёй «Групповой поиск с StructArray».

  4. Чтобы ознакомиться с ограничениями поиска для конкретных версий, ознакомьтесь с разделом «Ограничения StructArray».