Индексирование полей StructArray

Создайте индексы для подполей StructArray перед выполнением векторного поиска или ускорением скалярной фильтрации. Для поля StructArray целевым объектом индекса является путь к подполю, например chunks[emb_list_vector], chunks[emb] или chunks[section].

На этой странице используется коллекция tech_articles из раздела «Создание поля StructArray». Поле StructArray chunks содержит скалярные подполя для фильтрации и векторные подполя для поиска.

Перед началом работы

Убедитесь, что схема коллекции уже содержит поле StructArray « chunks » и что в неё вставлены данные.

Путь к подполюТипНазначение индекса
chunks[emb_list_vector]FLOAT_VECTORПоиск в EmbeddingList с использованием метрик MAX_SIM*.
chunks[emb]FLOAT_VECTORПоиск на уровне элементов с использованием обычных векторных метрик.
chunks[section]VARCHARКатегориальная фильтрация.
chunks[quality_score]FLOATЧисловая фильтрация и предикаты диапазонного типа.
chunks[has_code]BOOLБулева фильтрация.

Векторное поле или векторное подполе допускает только один индекс. Если вам нужен как поиск по EmbeddingList, так и поиск на уровне элементов, создайте два отдельных векторных подполя и проиндексируйте их по отдельности. На этой странице поле « chunks[emb_list_vector] » проиндексировано для поиска по EmbeddingList, а поле « chunks[emb] » — для поиска на уровне элементов.

Выбор индексов

Используйте режим поиска, чтобы выбрать семейство векторных метрик.

Цель поиска или фильтрацииЦелевой путьЧто выбрать
Поиск в EmbeddingListchunks[emb_list_vector]Семейство метрик « MAX_SIM* ».
Векторный поиск на уровне элементовchunks[emb]Обычное семейство векторных метрик, например COSINE, IP или L2.
Фильтрация по строке или категорииchunks[section]Скалярный индекс, поддерживаемый вашей целевой системой.
Фильтрация по числовому диапазонуchunks[quality_score], chunks[page]скалярный индекс, поддерживаемый вашей целью.
Фильтрация по булевому значениюchunks[has_code]Скалярный индекс, поддерживаемый вашей целевой платформой.

Поиск по EmbeddingList рассматривает векторы в подполе вектора StructArray как список вложений и возвращает результаты на уровне сущностей. Поиск на уровне элементов выполняет поиск по каждому элементу Struct независимо и может возвращать смещение найденного элемента.

Создание векторных индексов

В следующем примере создаются два векторных индекса. Первый индекс использует метрику « MAX_SIM* » для поиска по списку вложений. Второй индекс использует обычную векторную метрику для поиска на уровне элементов.

from pymilvus import MilvusClient

client = MilvusClient(
    uri="http://localhost:19530",
    token="root:Milvus",
)

index_params = client.prepare_index_params()

# Index for EmbeddingList search.
index_params.add_index(
    field_name="chunks[emb_list_vector]",
    index_name="chunks_emb_list_max_sim",
    index_type="HNSW",
    metric_type="MAX_SIM_COSINE",
    params={
        "M": 16,
        "efConstruction": 200,
    },
)

# Index for element-level search.
index_params.add_index(
    field_name="chunks[emb]",
    index_name="chunks_emb_cosine",
    index_type="HNSW",
    metric_type="COSINE",
    params={
        "M": 16,
        "efConstruction": 200,
    },
)

client.create_index(
    collection_name="tech_articles",
    index_params=index_params,
)

Предупреждение Не создавайте индекс с метрикой « MAX_SIM* » и индекс с обычной векторной метрикой для одного и того же подполя вектора. Если требуются оба режима поиска, запишите векторы в два отдельных подполя вектора и создайте по одному индексу для каждого подполя.

Создание скалярных индексов

Создавайте скалярные индексы на скалярных подполях StructArray, если вы используете их в фильтрах. Используйте тот же синтаксис пути, что и для structArray[subfield].

index_params = client.prepare_index_params()

index_params.add_index(
    field_name="chunks[section]",
    index_name="chunks_section_inverted",
    index_type="INVERTED",
)

index_params.add_index(
    field_name="chunks[has_code]",
    index_name="chunks_has_code_inverted",
    index_type="INVERTED",
)

index_params.add_index(
    field_name="chunks[quality_score]",
    index_name="chunks_quality_score_sort",
    index_type="STL_SORT",
)

index_params.add_index(
    field_name="chunks[page]",
    index_name="chunks_page_sort",
    index_type="STL_SORT",
)

client.create_index(
    collection_name="tech_articles",
    index_params=index_params,
)

Скалярные индексы не являются обязательными, но полезны, если скалярные подполя StructArray часто встречаются в фильтрах, таких как element_filter(chunks, $[quality_score] > 0.9) или MATCH_ANY(chunks, $[section] == "index").

Совместимость метрик индексов

Используйте приведенные ниже таблицы для выбора типа индекса и типа метрики для векторного подполя StructArray. Начните с конечной цели, а затем выберите семейство метрик в зависимости от режима поиска.

Выберите тип индекса и тип метрики Milvus из приведенных ниже таблиц совместимости.

Поиск по EmbeddingList использует метрики типа MAX_SIM*. Он рассматривает векторы в подполе векторного типа StructArray как список вложений и возвращает результаты на уровне сущностей.

Тип данных подполя вектораТип индексаТип метрики
FLOAT_VECTOR, FLOAT16_VECTOR, BFLOAT16_VECTORIVF_FLAT, IVF_FLAT_CC, HNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQ, DISKANNMAX_SIM, MAX_SIM_COSINE, MAX_SIM_IP, MAX_SIM_L2
INT8_VECTORHNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQMAX_SIM, MAX_SIM_COSINE, MAX_SIM_IP, MAX_SIM_L2
BINARY_VECTORHNSWMAX_SIM_HAMMING, MAX_SIM_JACCARD

Поиск на уровне элементов использует стандартные векторные метрики. Он выполняет поиск по каждому элементу структуры независимо и может возвращать смещение найденного элемента.

Тип данных векторного подполяТип индексаТип метрики
FLOAT_VECTOR, FLOAT16_VECTOR, BFLOAT16_VECTORFLAT, IVF_FLAT, IVF_FLAT_CC, IVF_SQ8, IVF_SQ_CC, IVF_PQ, SCANN, IVF_RABITQ, IVF_RABITQ_FASTSCAN, HNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQ, DISKANNL2, IP, COSINE
INT8_VECTORHNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQL2, IP, COSINE
BINARY_VECTORHNSWHAMMING, JACCARD
BINARY_VECTORBIN_FLATHAMMING, JACCARD, SUBSTRUCTURE, SUPERSTRUCTURE, MHJACCARD
BINARY_VECTORBIN_IVF_FLATHAMMING, JACCARD

Информацию о поддержке конкретных версий и других ограничениях см. в разделе «Ограничения StructArray».

Проверка индексов

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

indexes = client.list_indexes(
    collection_name="tech_articles",
)

print(indexes)

Вы также можете описать конкретный индекс, если ваша версия SDK предоставляет API для описания индексов.

index = client.describe_index(
    collection_name="tech_articles",
    index_name="chunks_emb_cosine",
)

print(index)

Правила индексирования

ПравилоПояснение
Используйте синтаксис путей для индексов подполей.Индексируйте chunks[emb], а не emb или chunks.emb.
Одно векторное подполе допускает один индекс.Используйте отдельные векторные подполя, если вам нужны разные семейства метрик.
Для поиска по EmbeddingList используйте метрику MAX_SIM*.Для запросов по EmbeddingList требуется индекс, построенный с использованием метрики MAX_SIM*.
Для поиска на уровне элементов используйте обычные векторные метрики.При поиске на уровне элементов используются данные запросов обычных векторных метрик, таких как COSINE, IP или L2.
Индексируйте скалярные подполя, которые появляются в фильтрах.Используйте типы скалярных индексов, поддерживаемые вашей целевой платформой.
Учитывайте ограничения на векторные поля.Общее количество векторных полей и векторных подполей ограничено. Перед добавлением большого количества векторных подполей ознакомьтесь с разделом «Ограничения StructArray».

Распространенные ошибки

  • Создание индекса на поле типа « chunks.emb » вместо « chunks[emb] ».

  • Создание только индекса MAX_SIM*, а затем попытка запустить поиск на уровне элементов в том же подполе.

  • Создание только обычного векторного индекса, а затем попытка выполнить поиск по EmbeddingList в том же подполе.

  • Повторное использование одного векторного подполя как для метрики MAX_SIM*, так и для обычной векторной метрики.

  • Отсутствие скалярных индексов для часто используемых фильтров StructArray.

  • Индексирование подполя StructArray, которое отсутствует в схеме Struct.

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

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

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

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