> 技术文档 > 【Milvus】索引(Indexes)的概述、分类 和 配置方法_milvus索引

【Milvus】索引(Indexes)的概述、分类 和 配置方法_milvus索引

Milvus 2.5.10(搭配 pymilvus 2.5.6),索引(Indexes) 是 Milvus 向量数据库中用于加速查询和搜索的关键机制。索引通过对数据(向量字段和标量字段)构建高效的数据结构,显著提升 向量相似性搜索标量过滤全文检索 的性能。Milvus 支持多种索引类型,针对不同字段类型(如 FLOAT_VECTORSPARSE_FLOAT_VECTORVARCHAR 等)优化查询效率。以下基于 Milvus 2.5.10 的官方文档(https://milvus.io/docs/index.md、https://milvus.io/docs/zh/index-explained.md)和其他相关资源,详细介绍 Milvus 中的索引,包括定义、特性、支持的索引类型、配置方法、代码示例、适用场景和注意事项。


1. 索引概述

索引 是 Milvus 中对集合(Collection)中字段数据预构建的数据结构,旨在加速查询和搜索操作。Milvus 的索引分为两类:

  • 向量索引:针对向量字段(如 FLOAT_VECTORSPARSE_FLOAT_VECTOR),优化相似性搜索(如 ANN,Approximate Nearest Neighbor)。
  • 标量索引:针对标量字段(如 INT64VARCHARJSON),加速过滤和精确匹配。

1.1 索引作用

  • 加速查询
    • 向量索引:减少向量相似性计算的复杂度(如欧氏距离、余弦相似度)。
    • 标量索引:优化范围查询、等值查询和全文检索。
  • 提升性能
    • 在大规模数据集中,索引将查询时间从线性扫描(O(n))降至近似对数或常数级别。
  • 支持复杂查询
    • 结合向量搜索和标量过滤,实现混合查询(Hybrid Search)。

1.2 索引特性

  • 字段级别:索引针对特定字段(如一个 FLOAT_VECTORVARCHAR 字段)创建。
  • 类型多样:支持多种索引算法(如 HNSWIVF_FLATINVERTED),适配不同场景。
  • 异步构建:索引构建是异步操作,可在后台完成。
  • 不可更改:索引创建后不可修改,需删除后重建。
  • 存储开销:索引会增加存储需求,需权衡性能和存储。

2. 支持的索引类型

Milvus 2.5.10 支持以下索引类型,分为 向量索引标量索引,每种类型针对特定字段和查询场景优化。

2.1 向量索引

向量索引用于加速向量相似性搜索,适用于 FLOAT_VECTORBINARY_VECTORFLOAT16_VECTORBFLOAT16_VECTORSPARSE_FLOAT_VECTOR 字段。以下是主要向量索引类型(参考 https://milvus.io/docs/index.md):

密集向量索引(FLOAT_VECTOR 等)
  • HNSW(Hierarchical Navigable Small World):
    • 描述:基于图结构的索引,适合高精度 ANN 搜索。
    • 参数
      • M:每个节点的出边数(4-64,影响精度和存储)。
      • efConstruction:构建时的搜索范围(8-512,影响构建速度)。
      • ef:搜索时的动态参数(影响查询速度)。
    • 适用场景:高精度搜索,中小规模数据集(百万级)。
    • 优点:高召回率,适合余弦相似度(COSINE)和欧氏距离(L2)。
    • 缺点:内存占用高,构建时间长。
  • IVF_FLAT(Inverted File with Flat):
    • 描述:基于聚类的索引,将向量分到多个簇(Cluster)。
    • 参数
      • nlist:簇数量(影响构建时间和查询精度)。
      • nprobe:搜索时检查的簇数(1-nlist,影响速度和精度)。
    • 适用场景:大规模数据集(亿级),高吞吐量。
    • 优点:存储开销低,适合大集群。
    • 缺点:精度低于 HNSW,需调优 nprobe
  • IVF_SQ8(Scalar Quantization):
    • 描述:基于量化的 IVF 索引,压缩向量数据。
    • 参数:同 IVF_FLAT
    • 适用场景:内存受限场景。
    • 优点:存储效率高。
    • 缺点:精度略低。
  • IVF_PQ(Product Quantization):
    • 描述:将向量分段并量化,进一步压缩。
    • 参数
      • nlistnprobe:同 IVF_FLAT
      • m:子空间数量(影响压缩率)。
    • 适用场景:超大规模数据,内存严格受限。
    • 优点:极高压缩率。
    • 缺点:精度损失较大。
  • FLAT
    • 描述:不构建索引,直接暴力搜索。
    • 适用场景:小数据集(<10,000),需要绝对精确结果。
    • 优点:最高精度,无索引开销。
    • 缺点:查询速度慢,O(n) 复杂度。
稀疏向量索引(SPARSE_FLOAT_VECTOR
  • AUTOINDEX
    • 描述:专为稀疏向量设计的索引,优化 BM25 全文检索。
    • 参数
      • metric_type=\"BM25\":使用 BM25 算法。
    • 适用场景:全文检索、RAG(Retrieval-Augmented Generation)。
    • 优点:高效支持关键词搜索,稀疏表示节省存储。
    • 缺点:依赖分词质量,仅限 BM25 场景。
    • 要求:需配合 FunctionType.BM25 函数将文本转换为稀疏向量。
二进制向量索引(BINARY_VECTOR
  • HNSWFLAT:支持二进制向量的相似性搜索(HAMMINGJACCARD 距离)。

2.2 标量索引

标量索引用于加速标量字段(如 INT64VARCHARJSON)的过滤和查询。以下是主要标量索引类型:

  • INVERTED(倒排索引):
    • 适用字段BOOLINT8INT16INT32INT64FLOATDOUBLEVARCHARJSON
    • 描述:构建倒排索引,快速查找包含特定值的记录。
    • 参数JSON 字段):
      • json_path:指定 JSON 键(如 metadata[\"category\"])。
      • json_cast_type:目标类型(如 \"varchar\")。
    • 适用场景
      • 精确匹配(如 category == \"electronics\")。
      • 全文检索(TEXT_MATCH 表达式)。
      • JSON 字段过滤。
    • 优点:高效支持等值和范围查询。
    • 缺点:存储开销随唯一值增加。
  • TRIE(前缀树):
    • 适用字段VARCHAR
    • 描述:基于前缀树的索引,优化字符串前缀匹配。
    • 适用场景:前缀查询(如 LIKE \"abc%\")。
    • 优点:高效支持前缀搜索。
    • 缺点:仅限前缀匹配,功能单一。
  • STL_SORT(标准模板库排序):
    • 适用字段BOOLINT8INT16INT32INT64FLOATDOUBLE
    • 描述:基于排序的索引,优化范围查询。
    • 适用场景:范围查询(如 price > 100)。
    • 优点:简单高效。
    • 缺点:仅支持排序字段。
  • BITMAP
    • 适用字段BOOLINT8INT16INT32INT64FLOATDOUBLEVARCHAR
    • 描述:基于位图的索引,优化高基数字段的等值查询。
    • 适用场景:高频等值查询(如 category == \"electronics\")。
    • 优点:低存储开销。
    • 缺点:范围查询效率较低。
  • JSON In-Memory Index
    • 适用字段JSON
    • 描述:内存中的倒排索引,优化 JSON 字段查询。
    • 适用场景:频繁的 JSON 键值查询。
    • 优点:高性能。
    • 缺点:内存占用高。

2.3 索引支持的度量类型

  • 密集向量
    • L2(欧氏距离)
    • IP(内积)
    • COSINE(余弦相似度)
  • 稀疏向量
    • BM25(全文检索相关性评分)
  • 二进制向量
    • HAMMING(汉明距离)
    • JACCARD(杰卡德距离)

3. 索引配置方法

在 Milvus 2.5.10 中,索引通过 MilvusClient.prepare_index_params()client.create_index() 配置。以下是配置步骤和代码示例。

3.1 配置步骤

  1. 定义 Schema
    • 指定字段类型(向量或标量)和约束。
    • 对于全文检索,添加 FunctionType.BM25 函数。
  2. 创建索引参数
    • 使用 MilvusClient.prepare_index_params()
    • 通过 add_index 添加索引配置(字段、类型、参数)。
  3. 构建索引
    • 调用 client.create_index(),异步构建索引。
  4. 加载集合
    • 使用 client.load_collection() 加载索引到内存。

3.2 代码示例:综合索引配置

以下示例展示如何为密集向量(FLOAT_VECTOR)、稀疏向量(SPARSE_FLOAT_VECTOR)、标量字段(VARCHARJSON)创建索引,结合全文检索、文本匹配和混合搜索。

from pymilvus import MilvusClient, DataType, AnnSearchRequest, RRFRanker, FunctionType, Functionfrom pymilvus.client.constants import ConsistencyLevelimport random# 连接 Milvusclient = MilvusClient(uri=\"http://localhost:19530\")try: # 创建数据库 client.create_database(db_name=\"test_db\") client.use_database(db_name=\"test_db\") # 创建 Schema schema = MilvusClient.create_schema(auto_id=True) schema.add_field( field_name=\"pk\", datatype=DataType.VARCHAR, is_primary=True, auto_id=True, max_length=100 ) schema.add_field( field_name=\"content\", datatype=DataType.VARCHAR, max_length=65535, enable_analyzer=True, enable_match=True, analyzer_params={\"type\": \"english\"} ) schema.add_field(field_name=\"sparse_vector\", datatype=DataType.SPARSE_FLOAT_VECTOR) schema.add_field(field_name=\"dense_vector\", datatype=DataType.FLOAT_VECTOR, dim=128) schema.add_field(field_name=\"metadata\", datatype=DataType.JSON) # 定义 BM25 函数 bm25_function = Function( name=\"content_bm25_sparse\", input_field_names=[\"content\"], output_field_names=[\"sparse_vector\"], function_type=FunctionType.BM25 ) schema.add_function(bm25_function) # 创建集合 client.create_collection( collection_name=\"index_collection\", schema=schema, consistency_level=ConsistencyLevel.Session ) # 创建索引 index_params = MilvusClient.prepare_index_params() # 稀疏向量索引(全文检索) index_params.add_index( field_name=\"sparse_vector\", index_type=\"AUTOINDEX\", metric_type=\"BM25\" ) # 密集向量索引(语义搜索) index_params.add_index( field_name=\"dense_vector\", index_type=\"HNSW\", metric_type=\"COSINE\", params={\"M\": 16, \"efConstruction\": 200} ) # 标量索引(文本匹配) index_params.add_index( field_name=\"content\", index_type=\"INVERTED\" ) # JSON 索引 index_params.add_index( field_name=\"metadata\", index_type=\"INVERTED\", index_name=\"json_category\", params={\"json_path\": \"metadata[\\\"category\\\"]\", \"json_cast_type\": \"varchar\"} ) client.create_index(collection_name=\"index_collection\", index_params=index_params) # 插入数据 data = [ { \"content\": \"Milvus supports hybrid search with BM25 and dense vectors.\", \"dense_vector\": [random.random() for _ in range(128)], \"metadata\": {\"category\": \"database\"} }, { \"content\": \"AI applications benefit from vector databases.\", \"dense_vector\": [random.random() for _ in range(128)], \"metadata\": {\"category\": \"AI\"} } ] client.insert(collection_name=\"index_collection\", data=data) # 加载集合 client.load_collection(collection_name=\"index_collection\") # 混合搜索 query_text = \"vector database\" dense_query_vector = [random.random() for _ in range(128)] sparse_request = AnnSearchRequest( data=[query_text], anns_field=\"sparse_vector\", param={\"metric_type\": \"BM25\"}, limit=2, expr=\"TEXT_MATCH(content, \'vector\') and metadata[\\\"category\\\"] == \\\"database\\\"\" ) dense_request = AnnSearchRequest( data=[dense_query_vector], anns_field=\"dense_vector\", param={\"metric_type\": \"COSINE\", \"params\": {\"ef\": 64}}, limit=2 ) results = client.hybrid_search( collection_name=\"index_collection\", reqs=[sparse_request, dense_request], ranker=RRFRanker(), limit=2, output_fields=[\"content\", \"metadata\"], consistency_level=ConsistencyLevel.Strong ) print(\"Hybrid search results:\") for result in results[0]: print(f\"Document: {result[\'entity\'][\'content\']}, Metadata: {result[\'entity\'][\'metadata\']}, Score: {result[\'distance\']}\")except Exception as e: print(f\"Error: {e}\")finally: # 清理 client.drop_collection(collection_name=\"index_collection\") client.drop_database(db_name=\"test_db\")

输出示例

Hybrid search results:Document: Milvus supports hybrid search with BM25 and dense vectors., Metadata: {\'category\': \'database\'}, Score: 0.912Document: AI applications benefit from vector databases., Metadata: {\'category\': \'AI\'}, Score: 0.745

代码说明

  • Schema
    • 包含 pk(主键)、contentVARCHAR,支持全文检索和文本匹配)、sparse_vector(BM25)、dense_vector(语义搜索)、metadataJSON)。
    • 添加 FunctionType.BM25 函数,将 content 转换为 sparse_vector
  • 索引
    • sparse_vectorAUTOINDEX(BM25)。
    • dense_vectorHNSW(COSINE)。
    • contentINVERTED(文本匹配)。
    • metadataINVERTED(JSON 键值查询)。
  • 混合搜索
    • 稀疏向量搜索:BM25,结合 TEXT_MATCH 和 JSON 过滤。
    • 密集向量搜索:HNSW,COSINE 度量。
    • 使用 RRFRanker 融合结果。

4. 索引选择建议

选择索引类型时,需权衡数据规模、查询需求和资源限制:

4.1 向量索引选择

  • HNSW
    • 适合:中小规模数据集(<10M),高精度要求(如推荐系统)。
    • 参数建议:M=16efConstruction=200ef=64
  • IVF_FLAT
    • 适合:大规模数据集(>10M),高吞吐量(如搜索引擎)。
    • 参数建议:nlist=1024nprobe=10-100
  • IVF_SQ8/IVF_PQ
    • 适合:内存受限场景(嵌入式设备)。
    • 参数建议:m=16(PQ),nprobe=10
  • FLAT
    • 适合:小数据集(<10K),绝对精确(如学术实验)。
  • AUTOINDEX
    • 适合:全文检索(BM25),稀疏向量场景。
    • 要求:配合 FunctionType.BM25

4.2 标量索引选择

  • INVERTED
    • 适合:等值查询、全文检索、JSON 字段过滤。
    • 示例:category == \"electronics\"TEXT_MATCH(content, \'AI\')
  • TRIE
    • 适合:前缀查询(如 LIKE \"abc%\")。
  • STL_SORT
    • 适合:范围查询(如 price > 100)。
  • BITMAP
    • 适合:高基数字段的等值查询。

4.3 索引优化

  • 数据规模:大数据集优先 IVF_FLATIVF_PQ,小数据集用 HNSWFLAT
  • 查询模式:频繁等值查询用 INVERTED,前缀查询用 TRIE
  • 存储限制:压缩索引(如 IVF_SQ8)适合内存受限环境。
  • 混合查询:为向量和标量字段都创建索引,支持复杂过滤。

5. 注意事项

  • 版本兼容性
    • 确保使用 Milvus 2.5.10 和 pymilvus 2.5.6(pip show pymilvus)。
    • AUTOINDEX 和 BM25 功能在 2.5.x 中稳定支持。
  • 索引限制
    • 每个字段只能有一种索引类型。
    • 索引创建后不可修改,需删除后重建。
  • 性能影响
    • 索引构建耗时,建议异步构建(async_=True)。
    • 索引增加存储开销,评估数据规模和字段基数。
  • 错误处理
    • 确保字段类型与索引类型匹配(如 SPARSE_FLOAT_VECTOR 只支持 AUTOINDEX)。
    • 示例:
      try: client.create_index(...)except Exception as e: print(f\"Error: {e}\")
  • 已知问题
    • 早期版本(如 2.5.0-beta)中 AUTO_INDEX 可能导致错误,2.5.10 已修复(https://milvus.io/docs/index.md)。

6. 总结

Milvus 2.5.10 的索引(Indexes) 是加速向量和标量查询的核心机制,支持密集向量(HNSWIVF_FLAT)、稀疏向量(AUTOINDEX)和标量字段(INVERTEDTRIE)的多种索引类型。向量索引优化相似性搜索,标量索引加速过滤和全文检索,结合分析器和 BM25 实现高效的混合搜索。