跳到主要内容

为 StructArray Field 创建 Index

在运行 Vector Search 或加速 Scalar Filtering 前,请先在 StructArray subfield 上创建 Index。对于 StructArray Field,Index 目标是 chunks[emb_list_vector]chunks[emb]chunks[section] 等 subfield path。

本文使用 创建 StructArray Field 中的 tech_articles Collection。chunks StructArray Field 包含用于 Filtering 的 Scalar subfield,以及用于 Search 的 Vector subfield。

开始之前

确保 Collection Schema 已包含 chunks StructArray Field,并且已经插入数据。

Subfield path类型Index 用途
chunks[emb_list_vector]FLOAT_VECTOR基于 MAX_SIM* metric 的 EmbeddingList Search。
chunks[emb]FLOAT_VECTOR基于常规 Vector metric 的 Element-level Search。
chunks[section]VARCHAR分类过滤。
chunks[quality_score]FLOAT数值过滤和范围类 predicate。
chunks[has_code]BOOL布尔值过滤。
📘说明

一个 Vector Field 或 Vector subfield 只能接受一个 Index。如果同时需要 EmbeddingList Search 和 Element-level Search,请创建两个独立的 Vector subfield 并分别创建 Index。在本文中,chunks[emb_list_vector] 为 EmbeddingList Search 创建 Index,chunks[emb] 为 Element-level Search 创建 Index。

选择 Index

使用搜索模式选择 Vector metric 类型族。

Search 或 Filter 目标目标路径选择内容
EmbeddingList Searchchunks[emb_list_vector]MAX_SIM* metric 类型族。
Element-level Vector Searchchunks[emb]常规 Vector metric 类型族,例如 COSINEIPL2
按字符串或分类过滤chunks[section]目标支持的 Scalar Index。
按数值范围过滤chunks[quality_score]chunks[page]目标支持的 Scalar Index。
按布尔值过滤chunks[has_code]目标支持的 Scalar Index。

EmbeddingList Search 会把 StructArray Vector subfield 中的 Vector 视为 EmbeddingList,并返回 Entity 级结果。Element-level Search 会独立搜索每个 Struct 元素,并且可以返回匹配元素的偏移量。

创建 Vector Index

以下示例创建两个 Vector Index。第一个 Index 为 EmbeddingList Search 使用 MAX_SIM* metric。第二个 Index 为 Element-level Search 使用常规 Vector metric。

python
from pymilvus import MilvusClient

client = MilvusClient(
uri="YOUR_CLUSTER_ENDPOINT",
token="YOUR_CLUSTER_TOKEN",
)

index_params = client.prepare_index_params()

# Index for EmbeddingList search.
index_params.add_index(
field_name="chunks[emb_list_vector]",
index_name="chunks_emb_list_max_sim",
index_type="HNSW",
metric_type="MAX_SIM_COSINE",
params={
"M": 16,
"efConstruction": 200,
},
)

# Index for element-level search.
index_params.add_index(
field_name="chunks[emb]",
index_name="chunks_emb_cosine",
index_type="HNSW",
metric_type="COSINE",
params={
"M": 16,
"efConstruction": 200,
},
)

client.create_index(
collection_name="tech_articles",
index_params=index_params,
)

对 StructArray Vector subfield 使用 AUTOINDEX

python
index_params = client.prepare_index_params()

index_params.add_index(
field_name="chunks[emb_list_vector]",
index_name="chunks_emb_list_auto",
index_type="AUTOINDEX",
metric_type="MAX_SIM_COSINE",
)

index_params.add_index(
field_name="chunks[emb]",
index_name="chunks_emb_auto",
index_type="AUTOINDEX",
metric_type="COSINE",
)

client.create_index(
collection_name="tech_articles",
index_params=index_params,
)
🚧警告

不要在同一个 Vector subfield 上同时创建 MAX_SIM* Index 和常规 Vector-metric Index。如果同时需要两种搜索模式,请将 Vector 写入两个独立的 Vector subfield,并在每个 subfield 上分别创建一个 Index。

创建 Scalar Index

当你在 Filter 中使用 StructArray Scalar subfield 时,请在这些 subfield 上创建 Scalar Index。使用相同的 structArray[subfield] 路径语法。

python
index_params = client.prepare_index_params()

index_params.add_index(
field_name="chunks[section]",
index_name="chunks_section_inverted",
index_type="INVERTED",
)

index_params.add_index(
field_name="chunks[has_code]",
index_name="chunks_has_code_inverted",
index_type="INVERTED",
)

index_params.add_index(
field_name="chunks[quality_score]",
index_name="chunks_quality_score_sort",
index_type="STL_SORT",
)

index_params.add_index(
field_name="chunks[page]",
index_name="chunks_page_sort",
index_type="STL_SORT",
)

client.create_index(
collection_name="tech_articles",
index_params=index_params,
)

对 StructArray Scalar subfield 使用 AUTOINDEX

python
index_params = client.prepare_index_params()

index_params.add_index(
field_name="chunks[section]",
index_name="chunks_section_auto",
index_type="AUTOINDEX",
)

index_params.add_index(
field_name="chunks[has_code]",
index_name="chunks_has_code_auto",
index_type="AUTOINDEX",
)

index_params.add_index(
field_name="chunks[quality_score]",
index_name="chunks_quality_score_auto",
index_type="AUTOINDEX",
)

index_params.add_index(
field_name="chunks[page]",
index_name="chunks_page_auto",
index_type="AUTOINDEX",
)

client.create_index(
collection_name="tech_articles",
index_params=index_params,
)

Scalar Index 是可选的,但当 StructArray Scalar subfield 经常出现在 Filter 中时很有用,例如 element_filter(chunks, $[quality_score] > 0.9)MATCH_ANY(chunks, $[section] == "index")

Index metric 兼容性

使用以下表格为 StructArray Vector subfield 选择 Index type 和 metric type。先从目标开始,再根据搜索模式选择 metric 类型族。

从以下兼容性表中选择 Milvus Index type 和 metric type。

EmbeddingList Search 使用 MAX_SIM* metric。它会把 StructArray Vector subfield 中的 Vector 视为 EmbeddingList,并返回 Entity 级结果。

Vector subfield data typeIndex typeMetric type
FLOAT_VECTOR, FLOAT16_VECTOR, BFLOAT16_VECTORIVF_FLAT, IVF_FLAT_CC, HNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQ, DISKANNMAX_SIM, MAX_SIM_COSINE, MAX_SIM_IP, MAX_SIM_L2
INT8_VECTORHNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQMAX_SIM, MAX_SIM_COSINE, MAX_SIM_IP, MAX_SIM_L2
BINARY_VECTORHNSWMAX_SIM_HAMMING, MAX_SIM_JACCARD

Element-level Search 使用常规 Vector metric。它会独立搜索每个 Struct 元素,并且可以返回匹配元素的偏移量。

Vector subfield data typeIndex typeMetric type
FLOAT_VECTOR, FLOAT16_VECTOR, BFLOAT16_VECTORFLAT, IVF_FLAT, IVF_FLAT_CC, IVF_SQ8, IVF_SQ_CC, IVF_PQ, SCANN, IVF_RABITQ, IVF_RABITQ_FASTSCAN, HNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQ, DISKANNL2, IP, COSINE
INT8_VECTORHNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQL2, IP, COSINE
BINARY_VECTORHNSWHAMMING, JACCARD
BINARY_VECTORBIN_FLATHAMMING, JACCARD, SUBSTRUCTURE, SUPERSTRUCTURE, MHJACCARD
BINARY_VECTORBIN_IVF_FLATHAMMING, JACCARD

对 StructArray Vector subfield 使用 AUTOINDEX。根据搜索模式所需的 metric 类型族选择 metric type。

Search modeVector subfield data typeIndex typeMetric type
EmbeddingList SearchFLOAT_VECTOR, FLOAT16_VECTOR, BFLOAT16_VECTOR, INT8_VECTORAUTOINDEXMAX_SIM, MAX_SIM_COSINE, MAX_SIM_IP, MAX_SIM_L2
EmbeddingList SearchBINARY_VECTORAUTOINDEXMAX_SIM_HAMMING, MAX_SIM_JACCARD
Element-level SearchFLOAT_VECTOR, FLOAT16_VECTOR, BFLOAT16_VECTOR, INT8_VECTORAUTOINDEXL2, IP, COSINE
Element-level SearchBINARY_VECTORAUTOINDEXHAMMING, JACCARD

关于特定版本支持和其他限制,请参阅 StructArray 限制

验证 Index

创建 Index 后,可以 describe Collection 或列出 Index,以确认预期的 subfield path 已创建 Index。

python
indexes = client.list_indexes(
collection_name="tech_articles",
)

print(indexes)

如果你的 SDK 版本暴露了 Index description API,也可以 describe 某个具体 Index。

python
index = client.describe_index(
collection_name="tech_articles",
index_name="chunks_emb_cosine",
)

print(index)

Index 规则

规则说明
对 subfield Index 使用路径语法。创建 chunks[emb] 的 Index,而不是 embchunks.emb
一个 Vector subfield 接受一个 Index。如果需要不同 metric 类型族,请使用独立的 Vector subfield。
对 EmbeddingList Search 使用 MAX_SIM* metric。EmbeddingList 查询数据需要使用 MAX_SIM* metric 构建的 Index。
对 Element-level Search 使用常规 Vector metric。Element-level Search 使用常规 Vector 查询数据和 COSINEIPL2 等 metric。
为出现在 Filter 中的 Scalar subfield 创建 Index。使用目标支持的 Scalar Index type。
注意 Vector Field 限制。Vector Field 和 Vector subfield 的总数有限。在添加多个 Vector subfield 前,请参阅 StructArray 限制。

常见错误

  • chunks.emb 上创建 Index,而不是 chunks[emb]

  • 只创建 MAX_SIM* Index,然后尝试在同一 subfield 上运行 Element-level Search。

  • 只创建常规 Vector Index,然后尝试在同一 subfield 上运行 EmbeddingList Search。

  • MAX_SIM* 和常规 Vector metric 复用同一个 Vector subfield。

  • 忘记为高频使用的 StructArray Filter 创建 Scalar Index。

  • 为 Struct Schema 中不存在的 StructArray subfield 创建 Index。

下一步

  1. 要运行 Entity 级 EmbeddingList Search 或 Element-level Vector Search,请阅读 使用 StructArray 进行基础向量搜索

  2. 要在 Search 期间过滤 StructArray Scalar subfield,请阅读 使用 StructArray 进行过滤搜索

  3. 要查看 Index 和 metric 限制,请阅读 StructArray 限制

Ctrl I