为 StructArray 字段创建索引
在执行向量搜索或加速标量过滤之前,请先在 StructArray 子字段上创建索引。对于 StructArray 字段,索引目标是一个子字段路径,例如chunks[emb_list_vector] 、chunks[emb] 或chunks[section] 。
本页使用“创建 StructArray 字段”中的tech_articles Collection。chunks StructArray 字段包含用于过滤的标量子字段和用于搜索的向量字段。
开始之前
请确保Collection Schema中已包含chunks StructArray字段,且数据已插入。
| 子字段路径 | 类型 | 索引用途 |
|---|---|---|
chunks[emb_list_vector] | FLOAT_VECTOR | 使用MAX_SIM* 指标进行EmbeddingList搜索。 |
chunks[emb] | FLOAT_VECTOR | 使用常规向量指标进行元素级搜索。 |
chunks[section] | VARCHAR | 分类过滤。 |
chunks[quality_score] | FLOAT | 数值过滤和范围式谓词。 |
chunks[has_code] | BOOL | 布尔过滤。 |
一个向量字段或向量子字段只能接受一个索引。如果您同时需要 EmbeddingList 搜索和元素级搜索,请创建两个独立的向量子字段,并分别对其进行索引。在此页面中,chunks[emb_list_vector] 已为 EmbeddingList 搜索建立索引,而chunks[emb] 已为元素级搜索建立索引。
选择索引
使用搜索模式选择向量度量族。
| 搜索或筛选目标 | 目标路径 | 选择内容 |
|---|---|---|
| EmbeddingList 搜索 | chunks[emb_list_vector] | MAX_SIM* 度量族。 |
| 元素级向量搜索 | chunks[emb] | 常规向量度量族,例如COSINE 、IP 或L2 。 |
| 按字符串或类别筛选 | chunks[section] | 目标支持的标量索引。 |
| 按数值范围筛选 | chunks[quality_score],chunks[page] | 目标支持的标量索引。 |
| 按布尔值过滤 | chunks[has_code] | 目标支持的标量索引。 |
EmbeddingList 搜索将 StructArray 向量子字段中的向量视为嵌入列表,并返回实体级别的结果。元素级搜索会独立搜索每个 Struct 元素,并可返回匹配元素的偏移量。
创建向量索引
以下示例创建了两个向量索引。第一个索引使用MAX_SIM* 度量进行EmbeddingList搜索。第二个索引使用常规向量度量进行元素级搜索。
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,
)
警告
请勿在同一个向量子字段上同时创建MAX_SIM* 索引和常规向量度量索引。如果需要同时使用这两种搜索模式,请将向量写入两个独立的向量子字段,并在每个子字段上分别创建一个索引。
创建标量索引
当在过滤器中使用 StructArray 标量子字段时,请为其创建标量索引。使用与structArray[subfield] 路径相同的语法。
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 标量子字段频繁出现在过滤器(如element_filter(chunks, $[quality_score] > 0.9) 或MATCH_ANY(chunks, $[section] == "index") )中时非常有用。
索引度量兼容性
请参考以下表格,为 StructArray 向量子场选择索引类型和度量类型。请从目标开始,然后根据搜索模式选择度量族。
请从以下兼容性表中选择 Milvus 索引类型和度量类型。
EmbeddingList 搜索
EmbeddingList 搜索使用MAX_SIM* 度量。它将 StructArray 向量子字段中的向量视为嵌入列表,并返回实体级别的结果。
| 向量子场数据类型 | 索引类型 | 度量类型 |
|---|---|---|
FLOAT_VECTOR,FLOAT16_VECTOR,BFLOAT16_VECTOR | IVF_FLAT,IVF_FLAT_CC,HNSW,HNSW_SQ,HNSW_PQ,HNSW_PRQ,DISKANN | MAX_SIM,MAX_SIM_COSINE,MAX_SIM_IP,MAX_SIM_L2 |
INT8_VECTOR | HNSW,HNSW_SQ,HNSW_PQ,HNSW_PRQ | MAX_SIM,MAX_SIM_COSINE,MAX_SIM_IP,MAX_SIM_L2 |
BINARY_VECTOR | HNSW | MAX_SIM_HAMMING,MAX_SIM_JACCARD |
元素级搜索
元素级搜索使用常规向量度量。它会独立搜索每个 Struct 元素,并能返回匹配元素的偏移量。
| 向量子场数据类型 | 索引类型 | 度量类型 |
|---|---|---|
FLOAT_VECTOR,FLOAT16_VECTOR,BFLOAT16_VECTOR | FLAT,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,DISKANN | L2,IP,COSINE |
INT8_VECTOR | HNSW,HNSW_SQ,HNSW_PQ,HNSW_PRQ | L2,IP,COSINE |
BINARY_VECTOR | HNSW | HAMMING,JACCARD |
BINARY_VECTOR | BIN_FLAT | HAMMING,JACCARD,SUBSTRUCTURE,SUPERSTRUCTURE,MHJACCARD |
BINARY_VECTOR | BIN_IVF_FLAT | HAMMING,JACCARD |
有关特定版本的支持及其他限制,请参阅《StructArray 限制》。
验证索引
创建索引后,请描述Collection或列表索引,以确认预期的子字段路径已纳入索引。
indexes = client.list_indexes(
collection_name="tech_articles",
)
print(indexes)
如果您的 SDK 版本提供了索引描述 API,您还可以描述特定索引。
index = client.describe_index(
collection_name="tech_articles",
index_name="chunks_emb_cosine",
)
print(index)
索引规则
| 规则 | 说明 |
|---|---|
| 对子字段索引,请使用路径语法。 | 请使用索引chunks[emb] ,而不是emb 或chunks.emb 。 |
| 一个向量量子字段只能接受一个索引。 | 如果需要不同的度量家族,请使用独立的向量子字段。 |
请使用MAX_SIM* 指标进行 EmbeddingList 搜索。 | EmbeddingList 查询数据需要使用基于MAX_SIM* 度量构建的索引。 |
| 对于元素级搜索,请使用常规向量指标。 | 元素级搜索使用常规向量查询数据和诸如COSINE 、IP 或L2 等度量。 |
| 对出现在过滤器中的标量子字段进行索引。 | 请使用目标支持的标量索引类型。 |
| 请注意向量字段的限制。 | 向量字段和向量子字段的总数是有限的。在添加大量向量子字段之前,请参阅《StructArray 限制》。 |
常见错误
在 `
chunks.emb` 上创建索引,而不是在 `chunks[emb]` 上创建。仅创建
MAX_SIM*索引,然后尝试在同一子字段上运行元素级搜索。仅创建常规向量索引,随后却试图在同一子字段上执行 EmbeddingList 搜索。
将同一个向量子字段同时用于
MAX_SIM*和常规向量度量。忽略了高频使用的 StructArray 过滤器对应的标量索引。
对 Struct Schema 中不存在的 StructArray 子字段进行索引。
后续步骤
若要运行实体级 EmbeddingList 搜索或元素级向量搜索,请参阅《使用 StructArray 进行基础向量搜索》。
若要在搜索过程中过滤 StructArray 的标量子字段,请参阅《使用 StructArray 进行过滤搜索》。
如需了解索引和指标限制,请参阅《StructArray 限制》。