建立 StructArray 欄位
當某個實體需要包含一組有序的結構化元素清單時,請建立 StructArray 欄位。StructArray 欄位是一種 Array 欄位,其元素類型為 Struct。每個 Struct 元素皆遵循相同的架構,並可包含標量子欄位、向量子欄位,或兩者兼具。
本頁說明如何定義 Struct 模式、將其新增為 StructArray 欄位、選擇日後用於搜尋與篩選的子欄位,以及在插入或建立資料索引之前,了解適用的模式規則。
開始之前
本頁使用名為「tech_articles 」的集合。每個實體代表一篇技術文章,而「chunks 」欄位則將區塊層級的資料儲存為 Struct 元素。
| 欄位 | 類型 | 用途 |
|---|---|---|
doc_id | INT64 | 文章的主鍵。 |
title | VARCHAR | 文章標題。 |
category | VARCHAR | 文章層級的分類。 |
title_vector | FLOAT_VECTOR | 文章層級的向量欄位,稍後將在混合搜尋範例中使用。 |
chunks | ARRAY | 用於儲存片段層級文字、元資料及嵌入向量的 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 模式時,請從受支援的標量與向量類別中選擇子欄位類型。
| 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 欄位。 |
有關特定版本的支援、可為 null 的行為及其他限制,請參閱StructArray 限制。
建立具有 StructArray 欄位的集合
要建立 StructArray 欄位,請先定義每個元素所使用的 Struct 架構。接著新增一個 Array 欄位,並將其元素類型設定為 Struct。
建立集合架構。
新增集合層級的欄位,例如主鍵和文章層級的欄位。
為儲存於 StructArray 欄位內的元素建立 Struct 架構。
在 Struct 模式中新增標量與向量子欄位。
新增一個陣列欄位,並將其
element_type=DataType.STRUCT設為 Struct 模式。將 `
struct_schema` 設定為 `Struct` 模式。設定 `
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 限制》。
將 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 欄位,然後使用更新的 Struct 架構新增一個新的 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,
)
架構規則
| 規則 | 說明 |
|---|---|
| Struct 用作 Array 元素類型。 | 請使用element_type=STRUCT 建立 StructArray 欄位作為 Array 欄位。請勿將 Struct 建立為頂層集合欄位。 |
| 所有元素共用一個架構。 | 同一 StructArray 欄位中的每個 Struct 元素均遵循為該欄位所定義的 Struct 架構。 |
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` 建立為頂層集合欄位,而非將其用作 `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 限制》。