如何使用Milvus构建向量检索系统:从入门到实践
本文将带你从零开始了解Milvus向量数据库,学会使用它构建高效的向量检索系统,适用于RAG、推荐系统、以图搜图等场景。
一、什么是Milvus
Milvus 是一款全球领先的开源向量数据库,专注于嵌入向量(Embedding Vector)的海量存储、索引与检索。它能够轻松应对十亿级向量规模的近似最近邻(ANN)检索需求。
核心特点
- 高性能:毫秒级十亿向量检索
- 分布式架构:支持水平扩展,轻松应对数据增长
- 丰富的索引类型:支持 HNSW、IVF、DiskANN、SCANN 等多种索引
- 多语言SDK:Python、Java、Go、Node.js 等
- 云原生:支持 Kubernetes 部署和混合云架构
- 开源生态:与 LangChain、LlamaIndex 等RAG框架深度集成
典型应用场景
- RAG(检索增强生成):为大语言模型提供准确的上下文知识
- 以图搜图:根据图片向量相似度搜索相似图片
- 推荐系统:基于用户/物品向量相似度进行推荐
- 语义搜索:超越关键词匹配的真正语义理解搜索
- 异常检测:通过向量距离识别异常模式
二、快速开始
环境要求
- Docker & Docker Compose
- Python 3.8+
1. 使用Docker快速部署
# 下载 docker-compose.yml
wget https://github.com/milvus-io/milvus/releases/download/v2.4.0/milvus-standalone-docker-compose.yml -O docker-compose.yml
# 启动 Milvus 服务
docker compose up -d
启动后,Milvus服务默认监听在以下端口:
- 19530:gRPC 端口(SDK 连接用)
- 9091: metrics 端口(Prometheus 监控用)
- 2379:etcd 端口
- 9000:MinIO 端口(对象存储)
2. 安装Python SDK
pip install pymilvus
3. 连接Milvus
from pymilvus import MilvusClient
# 连接本地 Milvus
client = MilvusClient(uri="http://localhost:19530")
# 或使用Lite模式(无需部署服务器)
# client = MilvusClient("milvus_demo.db")
三、核心概念
在操作Milvus之前,需要了解几个核心概念:
| 概念 | 说明 |
|---|---|
| Collection(集合) | 相当于关系型数据库中的"表",是存储向量的基本单位 |
| Entity(实体) | Collection 中的一条记录/数据行 |
| Field(字段) | 实体中的具体字段,包含主键、向量、标量等 |
| Index(索引) | 用于加速向量检索的数据结构 |
| Partition(分区) | Collection 的逻辑分组,用于过滤和隔离数据 |
| Vector(向量) | 由Embedding模型生成的浮点数数组,代表数据的特征 |
四、实战:构建文档语义搜索
1. 创建集合
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="http://localhost:19530")
# 检查并删除已存在的集合
if client.has_collection(collection_name="doc_search"):
client.drop_collection(collection_name="doc_search")
# 创建集合
client.create_collection(
collection_name="doc_search",
dimension=768, # 向量维度,这里使用 all-MiniLM-L6-v2 的输出维度
metric_type="IP", # 内积(余弦相似度)
primary_field_name="id",
auto_id=True,
vector_field_name="embedding"
)
print("集合创建成功!")
2. 准备示例数据
# 模拟文档数据
documents = [
"Milvus是一个开源的向量数据库,由Zilliz公司开发",
"向量数据库专门用于存储和检索高维向量数据",
"HNSW是一种高效的近似最近邻搜索算法",
"RAG技术通过检索外部知识来增强大模型的生成能力",
"嵌入模型可以将文本转换为固定维度的向量表示",
"IVF索引通过将向量空间划分为多个簇来加速检索",
"Milvus支持分布式部署,可以水平扩展",
"相似度搜索可以应用于推荐系统和以图搜图",
]
# 使用 Sentence Transformers 生成向量
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("all-MiniLM-L6-v2")
# 将文档转换为向量
embeddings = model.encode(documents)
print(f"向量形状: {embeddings.shape}") # (8, 768)
# 准备插入数据
data = [
{"embedding": vec, "content": doc}
for vec, doc in zip(embeddings, documents)
]
3. 插入数据
# 插入数据到集合
result = client.insert(
collection_name="doc_search",
data=data
)
print(f"成功插入 {result['insert_count']} 条数据")
4. 创建索引
# 创建 HNSW 索引
client.create_index(
collection_name="doc_search",
field_name="embedding",
index_type="HNSW",
metric_type="IP",
index_params={
"M": 16, # 每个节点的最大连接数
"efConstruction": 200 # 构建索引时的搜索范围
}
)
# 加载集合到内存
client.load_collection(collection_name="doc_search")
print("索引创建并加载成功!")
5. 执行向量检索
# 查询:"什么是向量数据库?"
query_text = "什么是向量数据库?"
query_embedding = model.encode([query_text])
# 执行搜索
results = client.search(
collection_name="doc_search",
data=query_embedding,
limit=3, # 返回最相似的3条结果
output_fields=["content"], # 返回附加字段
search_params={
"metric_type": "IP",
"params": {"ef": 100} # 搜索时的搜索范围
}
)
# 打印结果
print(f"\n查询: {query_text}")
print("-" * 50)
for i, hit in enumerate(results[0]):
print(f"Top {i+1} - 相似度得分: {hit['distance']:.4f}")
print(f" 内容: {hit['entity']['content']}")
print()
6. 标量过滤
Milvus支持在向量检索的同时进行标量过滤:
# 假设我们有一个带分类字段的集合
results = client.search(
collection_name="doc_search",
data=query_embedding,
filter='category == "技术"', # 标量过滤条件
limit=3,
output_fields=["content", "category"],
search_params={"metric_type": "IP", "params": {"ef": 100}}
)
五、高级用法
1. 使用不同的索引类型
# IVF_FLAT 索引 —— 适合精确度要求较高的场景
client.create_index(
collection_name="doc_search",
field_name="embedding",
index_type="IVF_FLAT",
metric_type="IP",
index_params={"nlist": 1024} # 聚类中心数量
)
# DISKANN 索引 —— 适合超大规模数据,基于磁盘的检索
client.create_index(
collection_name="doc_search",
field_name="embedding",
index_type="DISKANN",
metric_type="IP",
index_params={
"search_list_size": 100
}
)
2. 稀疏向量检索
Milvus 2.4+ 支持稀疏向量(Sparse Vector),适用于 BM25 等稀疏嵌入场景:
from pymilvus import MilvusClient, DataType
client.create_collection(
collection_name="hybrid_search",
dimension=768,
schema_fields=[
MilvusClient.create_field_schema(
name="dense_embedding",
dtype=DataType.FLOAT_VECTOR,
dimension=768
),
MilvusClient.create_field_schema(
name="sparse_embedding",
dtype=DataType.SPARSE_FLOAT_VECTOR
),
MilvusClient.create_field_schema(
name="content",
dtype=DataType.VARCHAR,
max_length=65535
)
]
)
3. 与 LangChain 集成
from langchain_community.vectorstores import Milvus
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vector_store = Milvus.from_documents(
documents=documents,
embedding=embeddings,
connection_args={"uri": "http://localhost:19530"},
collection_name="langchain_docs"
)
docs = vector_store.similarity_search("Milvus是什么", k=3)
for doc in docs:
print(doc.page_content)
六、性能调优建议
- 索引选择
- 数据量 < 100万:HNSW(构建快、查询快)
- 数据量 100万-1亿:IVF_FLAT 或 IVF_PQ
-
数据量 > 1亿:DISKANN(节省内存)
-
参数调优
M越大,精度越高但内存消耗越大(一般 16-64)efConstruction越高,索引质量越好但构建时间越长-
ef越高,搜索结果越精确但查询越慢 -
硬件建议
- 内存:至少 32GB(大规模数据建议 128GB+)
- SSD:建议使用 NVMe SSD 加速数据读写
- CPU:多核处理器有助于并行检索
七、总结
Milvus 作为一款专业的向量数据库,在AI应用场景中发挥着越来越重要的作用。从RAG到推荐系统,从以图搜图到异常检测,掌握Milvus的使用将为你构建AI应用提供强大的数据存储和检索能力。
学习资源
- 官方文档:https://milvus.io/docs
- GitHub 仓库:https://github.com/milvus-io/milvus
- 在线试用:https://milvus.io/milvus-demos
- 社区 Discord:https://discord.gg/milvus
如果你有Milvus使用中的任何问题,欢迎在评论区交流讨论!