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

Index StructArray Fields

在运行向量搜索或加速标量过滤之前,请先为 StructArray 子字段创建 Index。对于 StructArray 字段,Index 目标是子字段路径,例如 chunks[emb_list_vector]chunks[emb]chunks[section]

本页使用 Create a StructArray Field 中的 tech_articles Collection。chunks StructArray 字段包含用于过滤的标量子字段和用于搜索的向量子字段。

Before you begin

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

子字段路径类型索引用途
chunks[emb_list_vector]FLOAT_VECTOR使用 MAX_SIM* metrics 进行 EmbeddingList search。
chunks[emb]FLOAT_VECTOR使用常规向量 metrics 进行元素级 search。
chunks[section]VARCHAR类别过滤。
chunks[quality_score]FLOAT数值过滤和范围类谓词。
chunks[has_code]BOOL布尔过滤。

一个 vector field 或 vector subfield 只能接受一个 index。如果你同时需要 EmbeddingList search 和元素级 search,请创建两个独立的 vector subfield,并分别为它们创建 index。在本页中,chunks[emb_list_vector] 用于 EmbeddingList search 的 index,chunks[emb] 用于元素级 search 的 index。

选择 Index

使用搜索模式选择向量 metric family。

搜索或过滤目标目标路径选择内容
EmbeddingList 搜索chunks[emb_list_vector]MAX_SIM* metric family。
Element-level vector search(元素级向量搜索)chunks[emb]常规 vector metric family,例如 COSINEIPL2
按字符串或类别过滤chunks[section]目标支持的 scalar index。
按数值范围过滤chunks[quality_score]chunks[page]目标支持的 scalar index。
按布尔值过滤chunks[has_code]目标支持的 scalar index。

EmbeddingList 搜索会将 StructArray 向量子字段中的向量视为 embedding list,并返回 Entity 级结果。Element-level search 会独立搜索每个 Struct 元素,并可返回匹配元素的 offset。

创建 vector indexes

以下示例创建两个 vector index。第一个 index 使用 MAX_SIM* metric,用于 EmbeddingList search。第二个 index 使用常规 vector metric,用于 element-level search。

Python
from pymilvus import MilvusClient

client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus",
)

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

警告 不要在同一个 vector subfield 上同时创建 MAX_SIM* index 和常规 vector-metric index。如果需要同时使用这两种 search mode,请将 vectors 写入两个单独的 vector subfields,并在每个 subfield 上分别创建一个 index。

Create scalar indexes

当你在 Filter 中使用 StructArray 标量子字段时,为这些子字段创建 scalar indexes。使用相同的 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,
)

scalar indexes 是可选的,但当 StructArray 标量子字段频繁出现在 Filter 中时会很有用,例如 element_filter(chunks, $[quality_score] > 0.9)MATCH_ANY(chunks, $[section] == "index")

Index metric compatibility

使用以下表格为 StructArray vector 子字段选择 index type 和 metric type。先从目标出发,然后根据 search mode 选择 metric family。

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

EmbeddingList search 使用 MAX_SIM* metric。它会将 StructArray 向量子字段中的 vector 视为一个 embedding list,并返回 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 使用常规向量 Metric。它会独立搜索每个 Struct 元素,并可返回匹配元素的 offset。

Vector subfield 数据类型Index 类型Metric 类型
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 Limits

验证 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 rules

规则说明
对 subfield index 使用路径语法。chunks[emb] 创建 index,而不是 embchunks.emb
一个 vector subfield 只接受一个 index。如果需要不同的 metric family,请使用单独的 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 类型。
注意 vector field 限制。vector field 和 vector subfield 的总数有限。添加大量 vector subfield 前,请参阅 StructArray Limits。

常见错误

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

  • 只创建 MAX_SIM* Index,却尝试在同一个 subfield 上运行元素级搜索。

  • 只创建常规 vector Index,却尝试在同一个 subfield 上运行 EmbeddingList 搜索。

  • 将同一个 vector subfield 同时用于 MAX_SIM* 和常规 vector metrics。

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

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

后续步骤

  1. 如需执行 entity-level EmbeddingList search 或 element-level vector search,请阅读 Basic Vector Search with StructArray。

  2. 如需在搜索期间过滤 StructArray scalar subfield,请阅读 Filtered Search with StructArray。

  3. 如需查看 index 和 metric 限制,请阅读 StructArray Limits