创建 StructArray 字段

当某个实体需要包含一个有序的结构化元素列表时,请创建一个 StructArray 字段。StructArray 字段是一种数组字段,其元素类型为 Struct。每个 Struct 元素遵循相同的 Schema,可以包含标量子字段、向量字段,或两者兼有。

本页面将介绍如何定义 Schema、将其添加为 StructArray 字段、选择用于后续搜索和过滤的子字段,以及在插入或索引数据之前了解适用的 Schema 规则。

开始之前

本页面使用名为tech_articles 的Collection。每个实体代表一篇技术文章,而chunks 字段将以Struct元素的形式存储块级数据。

字段类型用途
doc_idINT64文章的主键。
titleVARCHAR文章标题。
categoryVARCHAR文章级别的分类。
title_vectorFLOAT_VECTOR文章级向量字段,将在后面的混合搜索示例中使用。
chunksARRAY用于存储片段级文本、元数据和 Embeddings 的 StructArray 字段。

chunks StructArray 字段包含以下子字段。

子字段类型用途
textVARCHAR块文本。
sectionVARCHAR章节名称,例如indexsearchfilter
pageINT64片段的页码或逻辑位置。
quality_scoreFLOAT在标量过滤和范围示例中使用的块级评分。
has_codeBOOL该片段是否包含代码。
emb_list_vectorFLOAT_VECTOR用于使用MAX_SIM* 度量进行 EmbeddingList 搜索的向量字段。
embFLOAT_VECTOR用于常规向量指标下元素级搜索的向量子字段。

向量字段或向量子字段仅接受一个索引。如果您同时需要 EmbeddingList 搜索和元素级搜索,请定义两个独立的向量子字段。在此示例中,chunks[emb_list_vector] 用于 EmbeddingList 搜索,而chunks[emb] 用于元素级搜索。

支持的子字段数据类型

StructArray 字段为每个 Struct 子字段存储一个数组值。定义 Struct Schema 时,请从支持的标量和向量类型家族中选择子字段类型。

Struct 子字段的物理类型支持备注
Array受支持将子字段定义为DataType.BOOL
Array受支持将子字段定义为DataType.INT8DataType.INT16DataType.INT32DataType.INT64
Array受支持将子字段定义为DataType.FLOATDataType.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不支持StructArray 字段不支持 JSON 子字段。
Array不支持StructArray 字段不支持几何子字段和 GIS 函数。
Array不支持StructArray 字段不支持文本子字段。
Array不支持StructArray 字段不支持 Timestamptz 子字段和特定时间的表达式。
嵌套的ArrayArrayOfVectorStructArrayOfStruct不支持StructArray 字段不能包含嵌套数组、嵌套向量数组、嵌套 Struct 字段或嵌套 Array-of-Struct 字段。

有关特定版本的支持、可为空行为和其他限制,请参阅StructArray 限制

创建包含 StructArray 字段的 Collection

要创建 StructArray 字段,首先需定义每个元素所使用的 Struct Schema。然后添加一个 Array 字段,并将该字段的元素类型设置为 Struct。

  1. 创建Collection Schema。

  2. 添加Collection级字段,例如主键和文章级字段。

  3. 为存储在 StructArray 字段中的元素创建 Struct Schema。

  4. 向 Struct Schema 中添加标量和向量字段。

  5. 添加一个element_type=DataType.STRUCT 的Array字段。

  6. struct_schema 设置为Struct Schema。

  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]用作嵌入列表的向量字段。使用MAX_SIM* 进行EmbeddingList搜索。
chunks[emb]每个 Struct 元素独立使用的向量字段。元素级向量搜索。

使 StructArray 字段可为空

Milvus v3.0.x 支持可空的 StructArray 字段。可空的 StructArray 字段允许实体为整个 StructArray 字段存储 `null `。

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

警告 可空的 StructArray 字段仅在 Milvus v3.0.x 中可用。对于可空的 StructArray 字段,实体可以提供有效的 StructArray 值,也可以将整个字段设置为 `null`。插入有效的 StructArray 值时,所有子字段应均为空或具有有效值。 若插入的实体中部分子字段设置为 null 而其他子字段设置为有效值,将导致错误。详情请参阅《StructArray 限制》。

向现有 Collection 添加 StructArray 字段

Milvus v3.0.x 支持向现有 Collection 添加 StructArray 字段。所添加的 StructArray 字段必须为可为空的,因为 Collection 中已存在的实体不具备该新字段的值。

要向现有 Collection 添加 StructArray 字段,请先定义 Struct Schema。然后调用 `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字段,然后使用更新的Struct Schema添加一个新的StructArray字段。

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,
)

Schema规则

规则说明
Struct 用作数组元素类型。使用element_type=STRUCT 将 StructArray 字段创建为数组字段。请勿将 Struct 作为顶级 Collection 字段创建。
所有元素共享一个Schema。同一 StructArray 字段中的每个 Struct 元素均遵循为该字段定义的 Struct Schema。
max_capacity 是必需的。它限制了每个实体可以在 StructArray 字段中存储的 Struct 元素的数量。
仅允许使用受支持的子字段类型。请使用 StructArray 支持的标量和向量字段类型。请勿定义 JSON、Geometry、Text、Timestamptz、SparseFloatVector 或嵌套的 Struct / Array 子字段。
在进行向量搜索之前,向量子字段需要建立索引。在运行向量搜索之前,请在诸如chunks[emb_list_vector]chunks[emb] 之类的路径上创建索引。
一个向量量子字段对应一个索引。如果您同时需要 EmbeddingList 搜索和元素级搜索,请创建两个独立的向量子字段。
现有的 StructArray 子字段是固定的。创建 StructArray 字段后,请勿期望向该 StructArray 字段添加更多子字段。
Struct 内部不支持函数。请勿在 StructArray 字段内为字段或子字段定义函数。
标量子字段应符合过滤需求。仅当您需要在稍后对sectionquality_scorehas_code 等字段进行过滤、分组或输出时,才应添加这些字段。

常见错误

  • DataType.STRUCT 作为顶级Collection字段创建,而不是将其用作Array字段的元素类型。

  • 忘记在 StructArray 字段上设置max_capacity

  • 定义了不受支持的子字段类型,例如 JSON、Geometry、Text、Timestamptz、SparseFloatVector、嵌套 Array、嵌套 Struct 或 Array-of-Struct。

  • String 用作子字段类型。请使用VARCHAR 并设置max_length

  • 将同一个向量子字段同时用于 EmbeddingList 搜索和元素级搜索。

  • 仅添加向量子字段,而忽略过滤所需的标量子字段,例如sectionquality_scorehas_code

  • 将向量字段视为$[...] 的标量谓词输入。使用向量字段进行向量搜索,使用标量子字段进行标量谓词搜索。

  • 假设在现有 StructArray 字段创建后,可以向该字段添加新的子字段。

  • 使用chunks.embchunks.emb_list_vector 代替必需的路径语法chunks[emb]chunks[emb_list_vector]

  • 将可为空的 StructArray 行为视为在每个目标版本中均可用。

后续步骤

  1. 要将嵌套数据插入 StructArray 字段,请参阅《将数据插入 StructArray 字段》。

  2. 要创建向量和标量索引,请参阅《索引 StructArray 字段》。

  3. 要搜索 StructArray 向量子字段,请参阅《使用 StructArray 进行基本向量搜索》。

  4. 要查看支持的数据类型、可为空行为以及特定版本的限制,请参阅《StructArray 限制》。

翻译自DeepL

想要更快、更简单、更好用的 Milvus SaaS服务 ?

Zilliz Cloud是基于Milvus的全托管向量数据库,拥有更高性能,更易扩展,以及卓越性价比

免费试用 Zilliz Cloud
反馈

此页对您是否有帮助?