跳到主要内容
版本:v3.0.x

Create a StructArray Field

当一个 Entity 需要包含一个有序的结构化元素列表时,可以创建 StructArray field。StructArray field 是一种 Array field,其元素类型为 Struct。每个 Struct 元素都遵循相同的 Schema,并且可以包含标量子字段、向量子字段,或同时包含两者。

本页介绍如何定义 Struct schema、将其作为 StructArray field 添加、选择后续用于 Search 和 Filter 的子字段,并了解在插入或索引数据之前适用的 Schema 规则。

准备工作

本页使用名为 tech_articles 的 Collection。每个 Entity 表示一篇技术文章,chunks 字段以 Struct 元素的形式存储 chunk 级数据。

字段类型用途
doc_idINT64文章的主键。
titleVARCHAR文章标题。
categoryVARCHAR文章级类别。
title_vectorFLOAT_VECTOR文章级向量字段,稍后会在 Hybrid Search 示例中使用。
chunksARRAYStructArray 字段,用于存储 chunk 级文本、元数据和 Embedding。

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

子字段类型用途
textVARCHARChunk 文本。
sectionVARCHARSection 名称,例如 indexsearchfilter
pageINT64Chunk 的页码或逻辑位置。
quality_scoreFLOATChunk 级分数,用于标量过滤和范围示例。
has_codeBOOLChunk 是否包含代码。
emb_list_vectorFLOAT_VECTOR用于基于 MAX_SIM* metric 进行 EmbeddingList search 的向量子字段。
embFLOAT_VECTOR用于基于常规向量 metric 进行元素级搜索的向量子字段。

一个向量字段或向量子字段只能接受一个 Index。如果你同时需要 EmbeddingList search 和元素级搜索,请定义两个独立的向量子字段。在本示例中,chunks[emb_list_vector] 用于 EmbeddingList search,chunks[emb] 用于元素级搜索。

Supported subfield data types

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 字段不支持 sparse vector 子字段。
Array不支持使用 VARCHAR,而不是 String
Array不支持StructArray 字段不支持 JSON 子字段。
Array不支持StructArray 字段不支持 Geometry 子字段和 GIS 函数。
Array不支持StructArray 字段不支持 Text 子字段。
Array不支持StructArray 字段不支持 Timestamptz 子字段和时间专用表达式。
嵌套的 ArrayArrayOfVectorStructArrayOfStruct不支持StructArray 字段不能包含嵌套数组、嵌套向量数组、嵌套 Struct 字段或嵌套 Array-of-Struct 字段。

如需了解特定版本支持情况、nullable 行为和其他限制,请参阅 StructArray Limits

Create a collection with a StructArray field

要创建 StructArray field,首先定义每个元素使用的 Struct schema。然后添加一个 Array field,并将其元素类型设置为 Struct。

  1. 创建 collection schema。

  2. 添加 collection-level fields,例如主键和文章级字段。

  3. 为存储在 StructArray field 中的元素创建 Struct schema。

  4. 向 Struct schema 添加 scalar 和 vector subfields。

  5. 添加一个 Array field,并设置 element_type=DataType.STRUCT

  6. struct_schema 设置为该 Struct schema。

  7. 设置 max_capacity,限制每个 entity 可在该字段中存储的 Struct 元素数量。

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

Understand StructArray field paths

创建 StructArray 字段后,使用 structArray[subfield] 路径语法引用其子字段。创建索引、搜索向量子字段、输出子字段或构建标量 filter 时,都可以使用此语法。

路径含义常见用法
chunks[text]每个 Struct 元素中的 text 子字段。输出字段或标量过滤。
chunks[section]每个 chunk 的 section 标签。标量过滤。
chunks[quality_score]chunk 级质量分数。标量过滤或标量索引。
chunks[emb_list_vector]用作 embedding list 的向量子字段。使用 MAX_SIM* 的 EmbeddingList 搜索。
chunks[emb]每个 Struct 元素独立使用的向量子字段。元素级向量搜索。

将 StructArray 字段设置为 nullable

Milvus v3.0.x 支持 nullable StructArray 字段。nullable StructArray 字段允许 Entity 为整个 StructArray 字段存储 null

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

警告 nullable StructArray 字段仅在 Milvus v3.0.x 中可用。对于 nullable StructArray 字段,Entity 可以提供有效的 StructArray 值,也可以将整个字段设置为 null。插入有效的 StructArray 值时,所有子字段都应为 NULL 或具有有效值。如果插入的 Entity 中部分子字段设置为 NULL,而其他子字段设置为有效值,则会导致错误。详情请参阅 StructArray Limits

向现有 Collection 添加 StructArray field

Milvus v3.0.x 支持向现有 Collection 添加 StructArray field。新增的 StructArray field 必须为 nullable,因为 Collection 中已存在的 Entity 没有该新 field 的值。

要向现有 Collection 添加 StructArray field,请先定义 Struct schema。然后调用 add_collection_struct_field() 并设置 nullable=True

Python
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 field 后,对于新 field 的所有 subfield,已有 Entity 都会返回 null

创建 StructArray field 后,不能再向该已有 StructArray field 添加新的 subfield。如果之后需要更多元素属性,请调用 drop_collection_field() 删除该 StructArray field,然后使用更新后的 Struct schema 添加新的 StructArray field。

Python
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 rules

规则说明
Struct 用作 Array 元素类型。将 StructArray 字段创建为 Array 字段,并设置 element_type=STRUCT。不要将 Struct 创建为顶层 Collection 字段。
所有元素共享同一个 Schema。同一 StructArray 字段中的每个 Struct 元素都遵循为该字段定义的 Struct Schema。
必须设置 max_capacity它限制每个 Entity 可在 StructArray 字段中存储的 Struct 元素数量。
只允许使用支持的子字段类型。使用 StructArray 支持的 scalar 和 vector 子字段类型。不要定义 JSON、Geometry、Text、Timestamptz、SparseFloatVector,或嵌套的 Struct / Array 子字段。
vector 子字段需要先创建 index 才能搜索。在运行 vector search 前,请在 chunks[emb_list_vector]chunks[emb] 等路径上创建 index。
一个 vector 子字段对应一个 index。如果你同时需要 EmbeddingList search 和 element-level search,请创建两个独立的 vector 子字段。
已有 StructArray 子字段是固定的。创建 StructArray 字段后,不要预期还能向同一个 StructArray 字段添加更多子字段。
Struct 内不支持 Function。不要为 StructArray 字段内的字段或子字段定义 function。
scalar 子字段应匹配 filter 需求。仅在之后需要 filter、group 或 output 时,才添加 sectionquality_scorehas_code 等字段。

常见错误

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

  • 忘记在 StructArray field 上设置 max_capacity

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

  • 使用 String 作为 subfield 类型。请使用 VARCHAR 并设置 max_length

  • 将同一个 vector subfield 同时用于 EmbeddingList search 和 element-level search。

  • 只添加 vector subfield,而忘记添加过滤所需的 scalar subfield,例如 sectionquality_scorehas_code

  • 将 vector subfield 当作 $[...] scalar predicate 输入。vector subfield 用于 vector search,scalar subfield 用于 scalar predicate。

  • 假设创建 field 后仍可向现有 StructArray field 添加新的 subfield。

  • 使用 chunks.embchunks.emb_list_vector,而不是必需的路径语法 chunks[emb]chunks[emb_list_vector]

  • 认为 nullable StructArray 行为在所有目标版本中都可用。

Next steps

  1. 要将嵌套数据插入 StructArray 字段,请阅读 Insert Data into StructArray Fields

  2. 要创建向量和标量 Index,请阅读 Index StructArray Fields

  3. 要搜索 StructArray 的向量子字段,请阅读 Basic Vector Search with StructArray。

  4. 要了解支持的数据类型、nullable 行为和特定版本限制,请阅读 StructArray Limits