为 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]常规向量度量族,例如COSINEIPL2
按字符串或类别筛选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 搜索使用MAX_SIM* 度量。它将 StructArray 向量子字段中的向量视为嵌入列表,并返回实体级别的结果。

向量子场数据类型索引类型度量类型
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

元素级搜索使用常规向量度量。它会独立搜索每个 Struct 元素,并能返回匹配元素的偏移量。

向量子场数据类型索引类型度量类型
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 限制》。

验证索引

创建索引后,请描述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] ,而不是embchunks.emb
一个向量量子字段只能接受一个索引。如果需要不同的度量家族,请使用独立的向量子字段。
请使用MAX_SIM* 指标进行 EmbeddingList 搜索。EmbeddingList 查询数据需要使用基于MAX_SIM* 度量构建的索引。
对于元素级搜索,请使用常规向量指标。元素级搜索使用常规向量查询数据和诸如COSINEIPL2 等度量。
对出现在过滤器中的标量子字段进行索引。请使用目标支持的标量索引类型。
请注意向量字段的限制。向量字段和向量子字段的总数是有限的。在添加大量向量子字段之前,请参阅《StructArray 限制》。

常见错误

  • 在 `chunks.emb ` 上创建索引,而不是在 `chunks[emb]` 上创建。

  • 仅创建MAX_SIM* 索引,然后尝试在同一子字段上运行元素级搜索。

  • 仅创建常规向量索引,随后却试图在同一子字段上执行 EmbeddingList 搜索。

  • 将同一个向量子字段同时用于MAX_SIM* 和常规向量度量。

  • 忽略了高频使用的 StructArray 过滤器对应的标量索引。

  • 对 Struct Schema 中不存在的 StructArray 子字段进行索引。

后续步骤

  1. 若要运行实体级 EmbeddingList 搜索或元素级向量搜索,请参阅《使用 StructArray 进行基础向量搜索》。

  2. 若要在搜索过程中过滤 StructArray 的标量子字段,请参阅《使用 StructArray 进行过滤搜索》。

  3. 如需了解索引和指标限制,请参阅《StructArray 限制》。

翻译自DeepL

想要更快、更简单、更好用的 Milvus SaaS服务 ?

Zilliz Cloud是基于Milvus的全托管向量数据库,拥有更高性能,更易扩展,以及卓越性价比

免费试用 Zilliz Cloud
反馈

此页对您是否有帮助?