Создание поля StructArray

Создайте поле StructArray, если одна сущность должна содержать упорядоченный список структурированных элементов. Поле StructArray — это поле типа Array, тип элементов которого — Struct. Каждый элемент Struct соответствует одной и той же схеме и может содержать скалярные подполя, векторные подполя или и те, и другие.

На этой странице показано, как определить схему Struct, добавить её в качестве поля StructArray, выбрать подполя для последующего поиска и фильтрации, а также разобраться в правилах схемы, которые применяются перед вставкой или индексированием данных.

Прежде чем начать

На этой странице используется коллекция с именем « tech_articles ». Каждая сущность представляет одну техническую статью, а поле « chunks » хранит данные на уровне фрагментов в виде элементов Struct.

ПолеТипНазначение
doc_idINT64Первичный ключ статьи.
titleVARCHARЗаголовок статьи.
categoryVARCHARКатегория на уровне статьи.
title_vectorFLOAT_VECTORВекторное поле на уровне статьи, используемое далее в примерах гибридного поиска.
chunksARRAYПоле StructArray, в котором хранятся текст на уровне фрагментов, метаданные и вложения.

Поле StructArray « chunks » содержит следующие подполя.

ПолеТипНазначение
textVARCHARТекст фрагмента.
sectionVARCHARИмя раздела, например index, search или filter.
pageINT64Номер страницы или логическое положение фрагмента.
quality_scoreFLOATОценка на уровне фрагмента, используемая в примерах скалярной фильтрации и диапазонов.
has_codeBOOLСодержит ли фрагмент код.
emb_list_vectorFLOAT_VECTORВекторное подполе для поиска в EmbeddingList с использованием метрик MAX_SIM*.
embFLOAT_VECTORВекторное подполе для поиска на уровне элементов с использованием обычных векторных метрик.

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

Поддерживаемые типы данных подполей

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

Физический тип подполя StructПоддержкаПримечания
ArrayПоддерживаетсяОпределите подполе как ` DataType.BOOL`.
ArrayПоддерживаетсяОпределите подполе как DataType.INT8, DataType.INT16, DataType.INT32 или DataType.INT64.
ArrayПоддерживаетсяОпределите подполе как DataType.FLOAT или DataType.DOUBLE.
ArrayПоддерживаетсяОпределите подполе как DataType.VARCHAR и установите max_length.
ArrayOfVectorПоддерживаетсяОпределите подполе как DataType.FLOAT_VECTOR и установите dim.
ArrayOfVectorПоддерживаетсяОпределите подполе как « DataType.FLOAT16_VECTOR » и установите значение « dim ».
ArrayOfVectorПоддерживаетсяОпределите подполе как « DataType.BFLOAT16_VECTOR » и установите значение « dim ».
ArrayOfVectorПоддерживаетсяОпределите подполе как « DataType.INT8_VECTOR » и установите значение « dim ».
ArrayOfVectorПоддерживаетсяОпределите подполе как « DataType.BINARY_VECTOR » и установите значение « dim ».
ArrayOfVectorНе поддерживаетсяПодполя в виде разреженных векторов не поддерживаются в полях StructArray.
ArrayНе поддерживаетсяИспользуйте VARCHAR, а не String.
ArrayНе поддерживаетсяПо podpola JSON не поддерживаются в полях StructArray.
ArrayНе поддерживаетсяПо podpolu «Геометрия» и функции ГИС не поддерживаются в полях StructArray.
ArrayНе поддерживаетсяПо podpolu «Текст» в полях StructArray не поддерживаются.
ArrayНе поддерживаетсяВ полях StructArray не поддерживаются подполя типа «Timestamptz» и выражения, связанные со временем.
Вложенные « Array », « ArrayOfVector », « Struct » или ArrayOfStructНе поддерживаетсяПоле StructArray не может содержать вложенные массивы, вложенные векторные массивы, вложенные поля Struct или вложенные поля Array-of-Struct.

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

Создание коллекции с полем StructArray

Чтобы создать поле StructArray, сначала определите схему Struct, используемую каждым элементом. Затем добавьте поле Array и установите для его типа элемента значение Struct.

  1. Создайте схему коллекции.

  2. Добавьте поля на уровне коллекции, такие как первичный ключ и поля на уровне статьи.

  3. Создайте схему Struct для элементов, хранящихся внутри поля StructArray.

  4. Добавьте скалярные и векторные подполя в схему Struct.

  5. Добавьте поле «Array» с параметром « element_type=DataType.STRUCT ».

  6. Укажите в качестве значения параметра « struct_schema » схему Struct.

  7. Установите параметр « max_capacity », чтобы ограничить количество элементов Struct, которые каждая сущность может хранить в этом поле.

from pymilvus import MilvusClient, DataType

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

schema = client.create_schema(
    auto_id=False,
    enable_dynamic_field=False,
)

# Collection-level fields.
schema.add_field(
    field_name="doc_id",
    datatype=DataType.INT64,
    is_primary=True,
)
schema.add_field(
    field_name="title",
    datatype=DataType.VARCHAR,
    max_length=512,
)
schema.add_field(
    field_name="category",
    datatype=DataType.VARCHAR,
    max_length=128,
)
schema.add_field(
    field_name="title_vector",
    datatype=DataType.FLOAT_VECTOR,
    dim=4,
)

# Struct schema used by each element in the StructArray field.
chunk_schema = client.create_struct_field_schema()
chunk_schema.add_field(
    field_name="text",
    datatype=DataType.VARCHAR,
    max_length=65535,
)
chunk_schema.add_field(
    field_name="section",
    datatype=DataType.VARCHAR,
    max_length=128,
)
chunk_schema.add_field(
    field_name="page",
    datatype=DataType.INT64,
)
chunk_schema.add_field(
    field_name="quality_score",
    datatype=DataType.FLOAT,
)
chunk_schema.add_field(
    field_name="has_code",
    datatype=DataType.BOOL,
)

# Vector subfield for EmbeddingList search.
chunk_schema.add_field(
    field_name="emb_list_vector",
    datatype=DataType.FLOAT_VECTOR,
    dim=4,
)

# Vector subfield for element-level search.
chunk_schema.add_field(
    field_name="emb",
    datatype=DataType.FLOAT_VECTOR,
    dim=4,
)

# Add the StructArray field.
schema.add_field(
    field_name="chunks",
    datatype=DataType.ARRAY,
    element_type=DataType.STRUCT,
    struct_schema=chunk_schema,
    max_capacity=1000,
)

client.create_collection(
    collection_name="tech_articles",
    schema=schema,
)

Понимание путей к полям StructArray

После создания поля StructArray обращайтесь к его подполям с использованием синтаксиса пути structArray[subfield]. Используйте этот синтаксис при создании индексов, поиске векторных подполей, выводе подполей или построении скалярных фильтров.

ПутьЗначениеТипичное использование
chunks[text]Поле « text » внутри каждого элемента Struct.Поле вывода или скалярная фильтрация.
chunks[section]Метка секции для каждого фрагмента.Скалярная фильтрация.
chunks[quality_score]Оценка качества на уровне фрагмента.Скалярная фильтрация или скалярный индекс.
chunks[emb_list_vector]Векторное подполе, используемое в качестве списка вложений.Поиск в EmbeddingList с помощью MAX_SIM*.
chunks[emb]Векторное подполе, используемое каждым элементом Struct независимо.Векторный поиск на уровне элементов.

Сделать поле StructArray допускающим нулевые значения

Milvus v3.0.x поддерживает поля StructArray, допускающие значение null. Поле StructArray, допускающее значение null, позволяет сущности хранить значения типа « null » для всего поля StructArray.

schema.add_field(
    field_name="chunks",
    datatype=DataType.ARRAY,
    element_type=DataType.STRUCT,
    struct_schema=chunk_schema,
    max_capacity=1000,
    nullable=True,
)

Предупреждение Поля StructArray, допускающие значение null, доступны только в Milvus v3.0.x. Для такого поля сущность может предоставлять допустимое значение StructArray или устанавливать для всего поля значение null. При вставке допустимого значения StructArray все подполя должны либо быть равны null, либо иметь допустимые значения. Вставка сущности, в которой некоторые подполя установлены в null, а другие — в допустимые значения, приводит к ошибке. Подробности см. в разделе «Ограничения StructArray».

Добавление поля StructArray в существующую коллекцию

Milvus v3.0.x поддерживает добавление поля StructArray в существующую коллекцию. Добавляемое поле StructArray должно быть допускать значение null, поскольку сущности, уже существующие в коллекции, не имеют значений для нового поля.

Чтобы добавить поле StructArray в существующую коллекцию, сначала определите схему Struct. Затем вызовите метод ` add_collection_struct_field() ` и задайте ` nullable=True`.

chunk_schema = client.create_struct_field_schema()
chunk_schema.add_field(
    field_name="text",
    datatype=DataType.VARCHAR,
    max_length=65535,
)
chunk_schema.add_field(
    field_name="section",
    datatype=DataType.VARCHAR,
    max_length=128,
)
chunk_schema.add_field(
    field_name="page",
    datatype=DataType.INT64,
)
chunk_schema.add_field(
    field_name="quality_score",
    datatype=DataType.FLOAT,
)
chunk_schema.add_field(
    field_name="has_code",
    datatype=DataType.BOOL,
)
chunk_schema.add_field(
    field_name="emb_list_vector",
    datatype=DataType.FLOAT_VECTOR,
    dim=4,
)
chunk_schema.add_field(
    field_name="emb",
    datatype=DataType.FLOAT_VECTOR,
    dim=4,
)

client.add_collection_struct_field(
    collection_name="tech_articles",
    field_name="chunks",
    struct_schema=chunk_schema,
    max_capacity=1000,
    nullable=True,
)

После добавления поля StructArray существующие сущности возвращают значение ` null ` для нового поля по всем его подполям.

После создания поля StructArray вы не сможете добавлять новые подполя к этому существующему полю StructArray. Если позже вам понадобятся дополнительные атрибуты элементов, вызовите метод drop_collection_field(), чтобы удалить поле StructArray, а затем добавьте новое поле StructArray с обновленной схемой Struct.

client.drop_collection_field(
    collection_name="tech_articles",
    field_name="chunks",
)

client.add_collection_struct_field(
    collection_name="tech_articles",
    field_name="chunks",
    struct_schema=updated_chunk_schema,
    max_capacity=1000,
    nullable=True,
)

Правила схемы

ПравилоОбъяснение
Struct используется в качестве типа элемента Array.Создайте поле StructArray как поле Array с помощью команды « element_type=STRUCT ». Не создавайте Struct в качестве поля коллекции верхнего уровня.
Все элементы используют одну схему.Каждый элемент Struct в одном и том же поле StructArray соответствует схеме Struct, определённой для этого поля.
max_capacity обязателен.Оно ограничивает количество элементов Struct, которые каждая сущность может хранить в поле StructArray.
Допускаются только поддерживаемые типы подполей.Используйте скалярные и векторные типы подполей, поддерживаемые StructArray. Не определяйте подполя типов JSON, Geometry, Text, Timestamptz, SparseFloatVector или вложенные подполя Struct / Array.
Для векторных подполей перед поиском необходимо создать индексы.Создайте индексы по путям типа chunks[emb_list_vector] или chunks[emb] перед запуском векторного поиска.
Одно векторное подполе имеет один индекс.Если вам нужен как поиск по EmbeddingList, так и поиск на уровне элементов, создайте два отдельных векторных подполя.
Существующие подполя StructArray являются фиксированными.После создания поля StructArray не рассчитывайте на добавление дополнительных подполей в это же поле StructArray.
Функции внутри Struct не поддерживаются.Не определяйте функции для полей или подполей внутри поля StructArray.
Скалярные подполя должны соответствовать требованиям фильтрации.Добавляйте такие поля, как section, quality_score или has_code, только в том случае, если вам понадобится впоследствии фильтровать, группировать или выводить их.

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

  • Создание DataType.STRUCT в качестве поля коллекции верхнего уровня вместо использования его в качестве типа элемента поля Array.

  • Забывание установить « max_capacity » для поля «StructArray».

  • Определение неподдерживаемых типов подполей, таких как JSON, Geometry, Text, Timestamptz, SparseFloatVector, вложенный массив, вложенная структура или массив структур.

  • Использование String в качестве типа подполя. Используйте VARCHAR и установите max_length.

  • Использование одного векторного подполя как для поиска по EmbeddingList, так и для поиска на уровне элементов.

  • Добавление только векторных подполей и игнорирование скалярных подполей, необходимых для фильтрации, таких как section, quality_score или has_code.

  • Рассмотрение векторных подполей в качестве входных данных для скалярных предикатов $[...]. Использование векторных подполей для векторного поиска, а скалярных подполей — для скалярных предикатов.

  • Предположение о том, что в существующее поле StructArray можно добавлять новые подполя после его создания.

  • Использование chunks.emb или chunks.emb_list_vector вместо обязательного синтаксиса пути chunks[emb] или chunks[emb_list_vector].

  • Рассмотрение поведения StructArray, допускающего нулевые значения, как доступного в любой целевой версии.

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

  1. Чтобы вставить вложенные данные в поле StructArray, ознакомьтесь с разделом «Вставка данных в поля StructArray».

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

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

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