创建 StructArray 字段
当某个实体需要包含一个有序的结构化元素列表时,请创建一个 StructArray 字段。StructArray 字段是一种数组字段,其元素类型为 Struct。每个 Struct 元素遵循相同的 Schema,可以包含标量子字段、向量字段,或两者兼有。
本页面将介绍如何定义 Schema、将其添加为 StructArray 字段、选择用于后续搜索和过滤的子字段,以及在插入或索引数据之前了解适用的 Schema 规则。
开始之前
本页面使用名为tech_articles 的Collection。每个实体代表一篇技术文章,而chunks 字段将以Struct元素的形式存储块级数据。
| 字段 | 类型 | 用途 |
|---|---|---|
doc_id | INT64 | 文章的主键。 |
title | VARCHAR | 文章标题。 |
category | VARCHAR | 文章级别的分类。 |
title_vector | FLOAT_VECTOR | 文章级向量字段,将在后面的混合搜索示例中使用。 |
chunks | ARRAY | 用于存储片段级文本、元数据和 Embeddings 的 StructArray 字段。 |
chunks StructArray 字段包含以下子字段。
| 子字段 | 类型 | 用途 |
|---|---|---|
text | VARCHAR | 块文本。 |
section | VARCHAR | 章节名称,例如index 、search 或filter 。 |
page | INT64 | 片段的页码或逻辑位置。 |
quality_score | FLOAT | 在标量过滤和范围示例中使用的块级评分。 |
has_code | BOOL | 该片段是否包含代码。 |
emb_list_vector | FLOAT_VECTOR | 用于使用MAX_SIM* 度量进行 EmbeddingList 搜索的向量字段。 |
emb | FLOAT_VECTOR | 用于常规向量指标下元素级搜索的向量子字段。 |
向量字段或向量子字段仅接受一个索引。如果您同时需要 EmbeddingList 搜索和元素级搜索,请定义两个独立的向量子字段。在此示例中,chunks[emb_list_vector] 用于 EmbeddingList 搜索,而chunks[emb] 用于元素级搜索。
支持的子字段数据类型
StructArray 字段为每个 Struct 子字段存储一个数组值。定义 Struct Schema 时,请从支持的标量和向量类型家族中选择子字段类型。
| 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 | 不支持 | StructArray 字段不支持 JSON 子字段。 |
Array | 不支持 | StructArray 字段不支持几何子字段和 GIS 函数。 |
Array | 不支持 | StructArray 字段不支持文本子字段。 |
Array | 不支持 | StructArray 字段不支持 Timestamptz 子字段和特定时间的表达式。 |
嵌套的Array 、ArrayOfVector 、Struct 或ArrayOfStruct | 不支持 | StructArray 字段不能包含嵌套数组、嵌套向量数组、嵌套 Struct 字段或嵌套 Array-of-Struct 字段。 |
有关特定版本的支持、可为空行为和其他限制,请参阅StructArray 限制。
创建包含 StructArray 字段的 Collection
要创建 StructArray 字段,首先需定义每个元素所使用的 Struct Schema。然后添加一个 Array 字段,并将该字段的元素类型设置为 Struct。
创建Collection Schema。
添加Collection级字段,例如主键和文章级字段。
为存储在 StructArray 字段中的元素创建 Struct Schema。
向 Struct Schema 中添加标量和向量字段。
添加一个
element_type=DataType.STRUCT的Array字段。将
struct_schema设置为Struct Schema。设置
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 字段内为字段或子字段定义函数。 |
| 标量子字段应符合过滤需求。 | 仅当您需要在稍后对section 、quality_score 或has_code 等字段进行过滤、分组或输出时,才应添加这些字段。 |
常见错误
将
DataType.STRUCT作为顶级Collection字段创建,而不是将其用作Array字段的元素类型。忘记在 StructArray 字段上设置
max_capacity。定义了不受支持的子字段类型,例如 JSON、Geometry、Text、Timestamptz、SparseFloatVector、嵌套 Array、嵌套 Struct 或 Array-of-Struct。
将
String用作子字段类型。请使用VARCHAR并设置max_length。将同一个向量子字段同时用于 EmbeddingList 搜索和元素级搜索。
仅添加向量子字段,而忽略过滤所需的标量子字段,例如
section、quality_score或has_code。将向量字段视为
$[...]的标量谓词输入。使用向量字段进行向量搜索,使用标量子字段进行标量谓词搜索。假设在现有 StructArray 字段创建后,可以向该字段添加新的子字段。
使用
chunks.emb或chunks.emb_list_vector代替必需的路径语法chunks[emb]或chunks[emb_list_vector]。将可为空的 StructArray 行为视为在每个目标版本中均可用。
后续步骤
要将嵌套数据插入 StructArray 字段,请参阅《将数据插入 StructArray 字段》。
要创建向量和标量索引,请参阅《索引 StructArray 字段》。
要搜索 StructArray 向量子字段,请参阅《使用 StructArray 进行基本向量搜索》。
要查看支持的数据类型、可为空行为以及特定版本的限制,请参阅《StructArray 限制》。