向量数据库系列文章目录
例如:第一章 向量数据库基础;第二章 Milvus 向量数据库
文章目录
- 向量数据库系列文章目录
- 前言
- Milvus向量数据库
- 一、Milvus
- 二、Milvus纯标量存储性能
- 三、Milvus安装
-
- 1.Milvus三种部署方式
- 2.Milvus硬件需求建议
- [3.docker部署Milvus Standalone](#3.docker部署Milvus Standalone)
- 4.容器:milvus-standalone、milvus-etcd、milvus-minio启动
- 5.增加/修改Milvus密码(可选)(失败)
- 6.增加/修改Milvus密码(可选)(成功)
- 7.安装客户端
- 8.milvus支持两个端口:19530、9091
- 四、Milvus与FAISS
- 五、Milvus多维向量与多向量字段
- 六、Python简易使用Milvus
-
- 1.使用pymilvus库能够对接Milvus向量数据库的第三方库。
- 2.连接到Milvus
- 3.connections.connect()与MilvusClient
- 4.数据库操作
- 5.集合加载/释放
- 6.创建集合
- 7.指定字段创建集合
- 8.Milvus数据类型
- 9.集合操作
- 10.集合信息
- 11.查看索引
- 12.删除索引
- 13.增加索引
- 14.Milvus异步操作
- 15.get获取数据
- 16.insert写入数据
- 17.search向量/标量混合查询数据
- 18.query纯标量查询数据
- 19.upsert修改数据
- [20.delete 删除数据](#20.delete 删除数据)
- 21.flush数据持久化
- 七、Milvus索引性能调优
- 八、LangChain使用Milvus作向量数据库
-
- 1.langchain-milvus库:能够在langchain中使用Milvus向量数据库。
- [2.需要安装Milvus的LangChain的插件:pip install langchain-milvus](#2.需要安装Milvus的LangChain的插件:pip install langchain-milvus)
- 3.创建向量数据库对象
- 4.向量数据库对象增加数据
- 5.创建检索器对象
- 6.自动新建标量字段
- 7.示例
- 总结
前言
本文主要整理 Milvus 向量数据库相关内容,包括 Milvus 概念、性能、索引类型、部署方式、Docker 安装、密码配置、MilvusClient 操作、Collection/Schema/Index、数据插入、搜索、查询以及常见索引参数等。
Milvus向量数据库
一、Milvus
1.Milvus
- Milvus是一个开源的向量数据库,专为高维向量数据的存储、查询和检索而设计。它支持多种类型的向量数据,如浮点数向量、整数向量等,并且提供了强大的向量相似度计算功能。
- Milvus采用分布式架构,可以轻松地扩展到大规模数据集,同时保证了数据的一致性和可用性。
- Milvus适用于处理和搜索大规模的高维向量数据,为AI应用和向量相似度搜索提供了加速引擎
- 在大多数情况下,Milvus的性能是其他向量数据库的2-5倍,它能实现万亿级向量的毫秒级相似性搜索,而且Milvus还是开源的向量数据库。
2.关键概念和特点
- 非结构化数据
- 非结构化数据指的是数据结构不规则,没有统一的预定义数据模型,不方便用数据库二维逻辑表来表现的数据。包括图片、视频、音频、自然语言等多种非结构化数据。
- Milvus可以处理非结构化数据,将其抽象为高维特征向量,从而实现高效的向量相似度搜索。
- 特征向量
- 特征向量是由embedding技术从离散变量(如图片、视频、音频、自然语言等各种非结构化数据)转变而来的连续向量。
- 通过向量表示,Milvus可以捕捉到数据的语义相似性,使得不同模态的数据之间可以相互匹配。
- 多模态搜索
- Milvus自带多模态功能,支持机器学习方法处理和理解来自不同源的多种模态信息,如文本、图像、音频和视频等。
- 这使得Milvus能够应用于多语言搜索、图像检索等多模态应用。
- 大模型赋能
- Milvus可以拓展大模型的边界,包括时间边界和空间边界。
- 时间边界的拓展:Milvus使得大模型具有"长期记忆",能够处理新信息。
- 空间边界的拓展:Milvus支持本地部署,解决大模型泄露隐私的问题。
- Milvus 2.0
- Milvus 2.0是一款云原生向量数据库,采用存储与计算分离的架构设计。
3.性能
- 性能提升
- 在新的Milvus 2.2 benchmark中,Milvus相比之前版本取得了50%以上的性能提升。
- 在1M向量串行执行的场景下,Milvus实现了3ms以下的延迟,整体QPS超过了ElasticSearch的10倍。
- 优化技巧
- Milvus性能可通过合理预计数据量、表数目大小、QPS参数等指标进行优化。
- 选择合适的索引类型和参数对于向量召回的性能至关重要,Milvus支持多种不同的索引,如Annoy、Faiss、HNSW、DiskANN等。
- 高可用性和弹性
- Milvus支持Kubernetes部署,以获得最佳可用性和弹性。
- Milvus还支持数据分片、数据持久性、流式数据摄入、向量和标量之间的混合搜索、时间旅行等高级功能。
- 云原生架构
- Milvus是云原生的,采用存储与计算分离的架构设计,支持海量向量数据的实时召回。
- Milvus基于FAISS、Annoy、HNSW等向量搜索库构建,解决稠密向量相似度检索的问题。
4.可扩展性
- 高可扩展性
- Milvus基于云原生分布式架构,能够实现百亿级别的向量索引扩展。
- Milvus支持存储与计算分离,离线在线一体化,使得数据库在应对不同场景时更加灵活。
- 生态支持
- Milvus与多个大模型生态系统深度集成,包括OpenAI、Langchain、Semantic Kernel、Llama-Index、AutoGPT、Towhee、Hugging face、Cohere等,为用户提供了丰富的应用场景和解决方案。
- 一键部署:
- 用户可以通过控制台快速创建Milvus向量数据库实例,全流程平台托管,无需进行任何安装、部署和运维操作,有效减少搭建和运维成本开销。
- 服务高可用
- Milvus采用云原生分布式构建,具备故障自动切换和自愈能力,全面提升实例可用性。
- Milvus还支持安全组管理,通过配置安全组,授权特定访问源,保证服务及数据的安全。
- 完善监控:
- Milvus向量数据库提供可视化监控面板,用户可以全面了解数据库实例的运行情况。
5.Milvus支持索引类型
- FLAT:适用于需要100%召回率且数据规模相对较小(百万级)的向量相似性搜索应用。
- IVF_FLAT:基于量化的索引,适用于追求查询准确性和查询速度之间理想平衡的场景(高速查询、要求高召回率)。
- IVF_SQ8:基于量化的索引,适用于磁盘或内存、显存资源有限的场景(高速查询、磁盘和内存资源有限、接受召回率的小幅妥协)。
- IVF_PQ:基于量化的索引,适用于追求高查询速度、低准确性的场景(超高速查询、磁盘和内存资源有限、接受召回率的实质性妥协)。
- HNSW:基于图的索引,适用于追求高查询效率的场景(高速查询、要求尽可能高的召回率、内存资源大的情景)。
- ANNOY:基于树的索引,适用于追求高召回率的场景(低维向量空间)。
- Milvus还支持其他一些索引类型,如SCANN、DISKANN等。以及AUTOINDEX,这是一种自动选择最合适索引类型的功能。
6.Milvus运行快原因
- 硬件感知优化:Milvus针对多种硬件架构和平台优化了性能,包括AVX512、SIMD、GPU和NVMe SSD。
- 高级搜索算法:Milvus支持多种内存和磁盘索引/搜索算法,包括IVF、HNSW、DiskANN等,所有这些算法都经过了深度优化。与FAISS和HNSWLib等流行实现相比,Milvus的性能提高了30%-70%。
- C++搜索引擎:向量数据库性能的80%以上取决于其搜索引擎。由于C++语言的高性能、底层优化和高效资源管理,Milvus将C++用于这一关键组件。最重要的是,Milvus集成了大量硬件感知代码优化,从汇编级向量到多线程并行化和调度,以充分利用硬件能力。
- 面向列:Milvus是面向列的向量数据库系统。其主要优势来自数据访问模式。在执行查询时,面向列的数据库只读取查询中涉及的特定字段,而不是整行,这大大减少了访问的数据量。此外,对基于列的数据的操作可以很容易地进行向量化,从而可以一次性在整个列中应用操作,进一步提高性能。
7.Milvus支持各种类型的搜索功能
- ANN 搜索:查找最接近查询向量的前K个向量。
- 过滤搜索:在指定的过滤条件下执行ANN搜索。
- 范围搜索:查找查询向量指定半径范围内的向量。
- 混合搜索:基于多个向量场进行ANN搜索。
- 全文搜索:基于BM25的全文搜索。
- Rerankers:根据附加标准或辅助算法调整搜索结果顺序,完善初始ANN搜索结果。
- 根据主键检索数据。
- 查询使用特定表达式检索数据。
二、Milvus纯标量存储性能
1.Milvus集合里不能没有向量字段,而且向量指定最小2维。
2.Milvus与内存/Redis对比
| 存储 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Milvus | 1. 数据持久化 2. 减少组件依赖 3. 支持标量过滤查询 | 1. 标量检索速度可能略慢于内存 2. 需要设计合理的集合结构 | 需要简化架构、长期持久化的场景 |
| 内存/Redis | 1. 键值查询极快 2. 适合高频读取 | 1. 需额外维护 Redis 2. 内存有限,可能丢失数据 | 对延迟敏感、能接受额外依赖的场景 |
3.性能
- Milvus的标量过滤性能通常略慢于Redis(内存键值存储),但差距在毫秒级,对大多数应用可忽略。如果标量字段建立了索引,速度会进一步提升。
- Redis的优势:纯内存操作,适合超高频读取(如每秒万次以上)。支持复杂数据结构(如 Hash、List)。
三、Milvus安装
1.Milvus三种部署方式
- Milvus Lite
- Milvus Lite是一个Python库,可导入到应用程序中。作为Milvus的轻量级版本,它非常适合在Jupyter笔记本或资源有限的智能设备上运行快速原型。
- Milvus Lite支持与Milvus其他部署相同的API。
- 与Milvus Lite交互的客户端代码也能与其他部署模式下的Milvus实例协同工作。
- Milvus Standalone(当前选用此部署方式)
- Milvus Standalone是单机服务器部署。
- Milvus Standalone的所有组件都打包到一个Docker镜像中,方便部署。
- Milvus Distributed
- Milvus Distributed可部署在Kubernetes集群上。
- 这种部署采用云原生架构,摄取负载和搜索查询分别由独立节点处理,允许关键组件冗余。它具有最高的可扩展性和可用性,并能灵活定制每个组件中分配的资源。
- Milvus Distributed是在生产中运行大规模向量搜索系统的企业用户的首选。
2.Milvus硬件需求建议
- 单机版本:4core CPU,16G内存,NVMe SSD。
- 技巧版本:8core CPU,128G内存,NVMe SSD。
3.docker部署Milvus Standalone
- 安装2.4.15版本的Milvus Standalone
- 安装docker并安装docker-compose
- 下载docker-compose.yaml文件
bash
wget https://github.com/milvus-io/milvus/releases/download/v2.4.15/milvus-standalone-docker-compose.yml -O docker-compose.yml
- 容器开机自启(可选)
- 容器开机自启需要修改docker-compose.yaml文件内容。
- 每个容器服务项中增加restart: always
- 网络服务不用增加
- 运行docker-compose.yaml文件(会自动下载镜像)
bash
docker compose up -d
4.容器:milvus-standalone、milvus-etcd、milvus-minio启动
- milvus-standalone容器使用默认设置为本地19530端口提供服务,并将其数据映射到当前文件夹中的volumes/milvus。
- milvus-etcd容器不向主机暴露任何端口,并将其数据映射到当前文件夹中的volumes/etcd。
- milvus-minio容器使用默认身份验证凭据在本地为端口9090和9091提供服务,并将其数据映射到当前文件夹中的volumes/minio。
5.增加/修改Milvus密码(可选)(失败)
- 使用命令进入镜像环境:docker exec -it milvus-standalone /bin/bash
- 修改/milvus/configs/milvus.yaml里的内容
- 将authorizationEnabled: false修改为authorizationEnabled: true
- 将defaultRootPassword: Milvus修改为defaultRootPassword: <密码>
- 如果没有vim/vi/nano,可以使用sed命令修改
bash
sed -i 's/authorizationEnabled: false/authorizationEnabled: true/' milvus.yaml
sed -i 's/defaultRootPassword: Milvus/defaultRootPassword: ************/' milvus.yaml
- 重启单个容器:docker restart milvus-standalone
6.增加/修改Milvus密码(可选)(成功)
- 使用命令进入镜像环境:docker exec -it milvus-standalone /bin/bash
- 修改/milvus/configs/milvus.yaml里的内容
- 将authorizationEnabled: false修改为authorizationEnabled: true
- 如果没有vim/vi/nano,可以使用sed命令修改
bash
sed -i 's/authorizationEnabled: false/authorizationEnabled: true/' milvus.yaml
- 重启单个容器:docker restart milvus-standalone
- 代码使用pymilvus库的connections和utility类,执行修改
- 先连接,后修改。使用alias定义连接别名,使用using来调用指定的连接
- 默认密码为Milvus,使用new_password参数设置新密码
代码
python
from pymilvus import connections, utility
connections.connect(
alias='default',
host='192.168.1.101',
port='19530',
user='root',
password='************',
)
utility.reset_password(
user="root",
old_password="************",
new_password="************",
using="default"
)
7.安装客户端
- 官方提供客户端attu,可用来连接Milvus服务,并提供UI操作界面。
- 下载安装包地址:https://github.com/zilliztech/attu/releases
- Windows版本选择attu-Setup-2.5.10.exe下载并安装。
8.milvus支持两个端口:19530、9091
- gRPC支持19530端口:连接不同Milvus sdk的Milvus服务器。
- gRPC也是基于TCP协议的
- RESTful API支持9091端口:使用HTTP客户端连接到Milvus服务器。
四、Milvus与FAISS
1.向量字段数量
- FAISS是一个纯粹的单向量索引库,每个数据表(集合)只能存储一个向量
- Milvus支持每个数据表存储多个向量。
2.非结构性数据
- FAISS不支持结构化数据,也就是说不能有其他标量地数据。
- Milvus支持结构化数据,也就是说能有多个标量地数据(标量数据如:一些属性数据,year,title等)。所以Milvus搜索时可以混合搜索(向量相似性 + 条件过滤)
3.对比
| 对比项 | FAISS | Milvus |
|---|---|---|
| 多向量支持 | ❌ 仅单向量 | ✅ 支持多个向量字段 |
| 结构化过滤 | ❌ 不支持 | ✅ 支持(如 year > 2000) |
| 分布式 | ❌ 单机 | ✅ 支持分布式 |
| 适用场景 | 小规模、简单相似性搜索 | 大规模、复杂多向量检索 |
五、Milvus多维向量与多向量字段
1.多向量
- 多向量与多维度
- 多维向量:一个向量里有很多维(如768维)
- 多个向量字段:一条数据里有多个独立的向量(多个embedding)
- Milvus 的多个向量字段
- 每个向量字段:都是一个独立的向量,都有自己的维度,都有自己的索引,都可以单独检索
- 场景:同一段文档有多种语义视角。
- 语义视角:内容语义(正文),标题语义,关键词语义
- 就是一段文档可有3个向量字段表示。而每个字段向量各有不同得维度表示。
代码
python
schema = CollectionSchema(
fields=[
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),
# 向量字段 1:正文语义
FieldSchema(name="content_vector", dtype=DataType.FLOAT_VECTOR, dim=768),
# 向量字段 2:标题语义
FieldSchema(name="title_vector", dtype=DataType.FLOAT_VECTOR, dim=384),
# 向量字段 3:关键词语义
FieldSchema(name="keyword_vector", dtype=DataType.FLOAT_VECTOR, dim=256),
]
)
2.Milvus表结构
- 假设一个RAG文档库,每条记录代表一个chunk。
- 每条记录得数据结构
python
Collection: document_chunks
┌─────────┬───────┬───────┐
│ 字段名 │ 类型 │ 说明 │
├─────────┼───────┼───────┤
│ id │ INT64 (PK) │ 主键 │
│ doc_id │ VARCHAR │ 文档ID │
│ chunk_index │ INT32 │ 第几个chunk │
│ content │ VARCHAR │ 原始文本 │
│ content_vector │ FLOAT_VECTOR │ 正文语义向量 │
│ title_vector │ FLOAT_VECTOR │ 标题语义向量 │
│ keyword_vector │ FLOAT_VECTOR │ 关键词向量 │
└─────────┴───────┴───────┘
- 有3个向量字段
python
content_vector -> dim = 768 (768维向量)
title_vector -> dim = 384 (354维向量)
keyword_vector -> dim = 256 (256维向量)
3.Milvus创建表格(collection)
代码
python
from pymilvus import FieldSchema, CollectionSchema, DataType
fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name="doc_id", dtype=DataType.VARCHAR, max_length=128),
FieldSchema(name="chunk_index", dtype=DataType.INT32),
FieldSchema(name="content", dtype=DataType.VARCHAR, max_length=65535),
# 向量字段
FieldSchema(name="content_vector", dtype=DataType.FLOAT_VECTOR, dim=768),
FieldSchema(name="title_vector", dtype=DataType.FLOAT_VECTOR, dim=384),
FieldSchema(name="keyword_vector", dtype=DataType.FLOAT_VECTOR, dim=256),
]
schema = CollectionSchema(
fields=fields,
description="Document chunks with multiple vector fields"
)
六、Python简易使用Milvus
1.使用pymilvus库能够对接Milvus向量数据库的第三方库。
- 安装pymilvus库:pip install pymilvus
2.连接到Milvus
- 使用MilvusClient()方法,连接到Milvus
- 参数:
- uri:要链接的Milvus服务的地址包括IP和port。
- db_name:Milvus服务的数据库名称。默认"default"
- user:Milvus服务账号名(可选)
- password:Milvus服务密码(可选)
- token:Milvus服务token(可选)
- 返回链接对象
- 返回链接对象后,使用close()断开连接
代码
python
from pymilvus import MilvusClient
client = MilvusClient(
db_name="default",
uri="http://192.168.1.101:19530",
# user="root",
# password="************",
)
3.connections.connect()与MilvusClient
- connections.connect()和MilvusClient都是连接Milvus的方式
- connections.connect()(旧版/Golang SDK风格):
- 来自pymilvus主要模块,属于较低层级的连接方式。
- 主要用于建立与管理Milvus的连接(通过alias别名支持多连接),但不直接提供数据操作的 API。
- 连接后需通过utility等具体类操作数据,API更面向Milvus的核心概念(如集合、分区、索引等)。
- MilvusClient(新版/Python SDK风格):
- 是PyMilvus 2.x引入的高级封装,提供更简单的、面向RESTful/gRPC接口的客户端。
- 直接集成常见操作(如插入、搜索、删除),API更简洁。
4.数据库操作
- 返回链接对象后,使用list_databases()方法,列出所有数据库。
- 返回链接对象后,使用create_database(db_name)方法,创建数据库。
- 如果数据库存在,创建会报错。
- 返回链接对象后,使用using_database(db_name)方法,进入/使用数据库。
- 返回链接对象后,使用drop_database(db_name)方法,删除数据库。
5.集合加载/释放
- 集合有一个加载或释放的状态。加载是指将集合的数据(包括向量和索引)从磁盘加载到内存(或GPU显存),以便进行高效的向量检索。
- 释放状态下的集合无法操作数据。新创建的集合会默认加载状态。
- Milvus不会对任何集合作自动加载的动作。
- 集合需要修改/新增索引时,需要在集合释放的状态下操作。
- 加载/释放状态
| 状态 | 是否可查询 | 内存占用 | 典型场景 |
|---|---|---|---|
| 加载 | 可检索 | 占用内存/显存 | 高频访问的集合 |
| 释放 | 不可检索 | 仅占磁盘 | 冷数据或归档数据 |
- 返回链接对象后,使用load_collection()方法加载集合,collection_name参数为集合名称字符串。
- 返回链接对象后,使用release_collection()方法释放集合,collection_name参数为集合名称字符串。
6.创建集合
- 使用IndexParams()方法创建索引对象。并使用索引对象的add_index()方法定义索引的内容。add_index()参数:
- field_name:指定添加索引的字段名。如"vector"
- index_type:索引类型,如"FLAT","IVF_FLAT","HNSW","ANNOY"等
- index_name:索引名称字符串,默认与字段名相同。
- metric_type:距离度量类型,如"L2"(欧氏距离),"IP"(内积),"COSINE" (余弦相似度)
- params:特定索引类型的额外参数。取决于使用的索引类型。如:
- 对于IVF_FLAT或IVF_SQ8索引,需要"nlist"参数,表示聚类中心数量。
- 对于HNSW索引,需要"efConstruction"参数,表示索引构建时的搜索范围。和"M"参数,表示每个节点的最大连接数
- 返回链接对象后,使用create_collection()方法,创建集合(数据库的表)
- 参数:
- collection_name:集合名称字符串,必须唯一。如:"my_collection"
- schema:集合的架构定义,可使用 MilvusClient.create_schema()创建的schema对象。如果提供此参数,dimension参数将被忽略
- dimension:单个向量字段的维度整数,用于生成向量嵌入的模型决定。如128,384,1536等。说明这个是单个字段的向量表。注意:如果提供了schema参数,并且schema中已经为向量字段设置了维度,则此参数将被忽略
- index_params:定义好内容的索引对象。如果不指定,默认AUTOINDEX
- drop_old:当集合已存在时是否先删除旧集合再创建新集合,默认False
- auto_id:是否自动生成主键ID,默认True,插入数据时不需要提供主键值
- enable_dynamic_field:是否启用动态字段,默认True,可在插入数据时添加架构中未定义的字段
- timeout:操作超时时间数(秒)。如果超时会抛出异常。默认None(不超时)
- consistency_level:一致性级别,可选:"Strong","Session","Bounded","Eventually"
- ttl:集合的生存时间(秒),超过此时间后数据将被自动删除。默认为0,表示永不过期
代码
python
from pymilvus import MilvusClient
from pymilvus.milvus_client import IndexParams
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
# 定义索引
index_params = IndexParams()
index_params.add_index(
field_name="title_vector",
index_type="FLAT",
metric_type="L2",
params={},
)
client.create_collection(
collection_name="my_collection",
dimension=128,
index_params=index_params,
)
7.指定字段创建集合
- 使用FieldSchema()方法,创建某一个字段对象,参数:
- name参数名
- dtype字段类型
- is_primary是否主键
- auto_id:是否自动生成主键ID
- dim:向量维度数值
- max_length:数据最长长度。
- CollectionSchema()方法,创建collection的纲要对象,参数:
- fields:字段对象列表
- description:描述字符串
- enable_dynamic_field:是否启用动态字段,默认True
- 返回链接对象后,再使用create_collection()方法,创建集合。参数如上。
代码
python
from pymilvus import MilvusClient, DataType, FieldSchema, CollectionSchema
from pymilvus.milvus_client import IndexParams
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
# 定义索引
index_params = IndexParams()
index_params.add_index(
field_name="vector",
index_type="FLAT",
metric_type="L2",
params={},
)
# 定义字段
fields = [
# 主键字段
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
# 向量字段,维度为128
FieldSchema(name="vector", dtype=DataType.FLOAT_VECTOR, dim=128),
# 文本字段
FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=512),
FieldSchema(name="producer", dtype=DataType.VARCHAR, max_length=256),
FieldSchema(name="creator", dtype=DataType.VARCHAR, max_length=256),
FieldSchema(name="creationdate", dtype=DataType.VARCHAR, max_length=256),
FieldSchema(name="title", dtype=DataType.VARCHAR, max_length=512),
FieldSchema(name="author", dtype=DataType.VARCHAR, max_length=256),
FieldSchema(name="moddate", dtype=DataType.VARCHAR, max_length=256),
FieldSchema(name="source", dtype=DataType.VARCHAR, max_length=256),
FieldSchema(name="total_pages", dtype=DataType.INT64),
FieldSchema(name="page", dtype=DataType.INT64),
FieldSchema(name="page_label", dtype=DataType.VARCHAR, max_length=256),
]
# 定义集合的schema
schema = CollectionSchema(
fields=fields,
description="这是一个带有自定义字段的示例集合",
enable_dynamic_field=True
)
# 创建集合
client.create_collection(
collection_name="my_collection",
schema=schema,
index_params=index_params,
)
# 查看集合结构
collection_info = client.describe_collection("my_collection")
print(collection_info)
结果
text
{
"collection_name": "my_collection",
"auto_id": True,
"num_shards": 1,
"description": "这是一个带有自定义字段的示例集合",
"fields": [
{
"field_id": 100,
"name": "id",
"description": "",
"type": <DataType.INT64: 5>,
"params": {},
"auto_id": True,
"is_primary": True,
},
{
"field_id": 101,
"name": "vector",
"description": "",
"type": <DataType.FLOAT_VECTOR: 101>,
"params": {"dim": 128},
},
...
{
"field_id": 112,
"name": "page_label",
"description": "",
"type": <DataType.VARCHAR: 21>,
"params": {"max_length": 256},
},
],
"functions": [],
"aliases": [],
"collection_id": 458490636546779991,
"consistency_level": 2,
"properties": {},
"num_partitions": 1,
"enable_dynamic_field": True,
"created_timestamp": 458494955174494213,
}
8.Milvus数据类型
| 常量 | 相当于常数 | 字段类型 | 描述 |
|---|---|---|---|
| BOOL | 1 | 标量 | 布尔类型 |
| INT8 | 2 | 标量 | 8位整型 |
| INT16 | 3 | 标量 | 16位整型 |
| INT32 | 4 | 标量 | 32位整型 |
| INT64 | 5 | 主键,标量 | 64位整型 |
| FLOAT | 10 | 标量 | 单精度浮点型 |
| DOUBLE | 11 | 标量 | 双精度浮点型 |
| VARCHAR | 21 | 主键,标量 | 字符串类型,max_length=65,535 |
| BINARY_VECTOR | 100 | 向量 | 二进制向量类型 |
| FLOAT_VECTOR | 101 | 向量 | 32位单精度浮点数向量 |
| FLOAT16_VECTOR | 102 | 向量 | 16位半精度浮点数向量 |
| BFLOAT16_VECTOR | 103 | 向量 | 16位半精度浮点数向量,比FLOAT16_VECTOR显存占用量更小,精度更低。 |
| SPARSE_FLOAT_VECTOR | 104 | 向量 | 稀疏向量,存储非零元素及其相应索引列表 |
| ARRAY | 22 | 复合 | 数组,就是python中的列表 |
| JSON | 23 | 复合 | json文档,就是python中的字典 |
| NONE | 0 | 空类型,无法设置为字段类型,milvus返回的格式, | |
| UNKNOWN | 999 | 未知类型,无法设置为字段类型,milvus返回的格式。 |
9.集合操作
- 返回链接对象后,使用list_collections()方法,列出所有集合
- 返回链接对象后,使用has_collection()方法,判断集合是否存在,参数collection_name为集合名称字符串
- 返回链接对象后,使用drop_collection()方法,删除集合,参数collection_name为集合名称字符串
代码
python
from pymilvus import MilvusClient
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
print(client.list_collections())
client.has_collection("example")
client.drop_collection("example")
结果
text
['example', 'my_collection', 'my_custom_collection', 'my_custom']
True
10.集合信息
- 返回链接对象后,使用describe_collection()方法获取集合信息,参数collection_name为集合名称字符串
- 返回集合属性字典
代码
python
from pymilvus import MilvusClient
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
collection_info = client.describe_collection(collection_name="my_collection")
print(collection_info)
结果
text
{
"collection_name": "my_collection",
"auto_id": False,
"num_shards": 1,
"description": "",
"fields": [
{
"field_id": 100,
"name": "id",
"description": "",
"type": <DataType.INT64: 5>,
"params": {},
"is_primary": True,
},
{
"field_id": 101,
"name": "vector",
"description": "",
"type": <DataType.FLOAT_VECTOR: 101>,
"params": {"dim": 128},
},
],
"functions": [],
"aliases": [],
"collection_id": 458490636546761400,
"consistency_level": 2,
"properties": {},
"num_partitions": 1,
"enable_dynamic_field": True,
"created_timestamp": 458494049925988359,
}
11.查看索引
- 返回链接对象后,使用list_indexes()方法,查看集合内所有索引名称的列表,参数collection_name为集合名称字符串
- 返回链接对象后,使用describe_index()方法,查看指定索引详情,参数collection_name为集合名称字符串,参数index_name为索引名称字符串。
代码
python
from pymilvus import MilvusClient
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
index_names = client.list_indexes(collection_name="my_collection")
print(index_names)
index_info = client.describe_index(
collection_name="my_collection",
index_name='vector' # 从上面获取的索引名称列表中选择
)
print(index_info) # 输出索引详细信息
结果
text
['vector']
{'index_type': 'AUTOINDEX', 'metric_type': 'COSINE', 'field_name': 'vector', 'index_name': 'vector', 'total_rows': 0, 'indexed_rows': 0, 'pending_index_rows': 0, 'state': 'Finished'}
12.删除索引
- 删除索引前,需要先释放集合,再删除。
- 返回链接对象后,使用release_collection()方法释放集合,参数collection_name为集合名称字符串。
- 返回链接对象后,使用drop_index()方法删除索引,参数collection_name为集合名称字符串。参数index_name为索引名称字符串,如"vector"
- 删除索引成功或失败,都是没有提示信息的。
代码
python
from pymilvus import MilvusClient
from pymilvus.milvus_client import IndexParams
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
client.release_collection(collection_name="my_collection")
client.drop_index(collection_name="my_collection", index_name="vector")
13.增加索引
- Milvus规定每个字段最多只能有一个索引。需要先删除再增加再加载。
- 使用IndexParams()和add_index()方法,创建有内容的索引对象。
- 返回链接对象后,使用create_index()方法修改索引,参数collection_name为集合名称字符串,参数index_params为index_params对象
- 返回链接对象后,使用load_collection()方法加载集合,参数collection_name为集合名称字符串。
代码
python
from pymilvus import MilvusClient
from pymilvus.milvus_client import IndexParams
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
index_params = IndexParams()
index_params.add_index(
field_name="vector",
index_type="FLAT",
metric_type="L2",
params={},
)
client.create_index(collection_name="my_collection", index_params=index_params)
client.load_collection(collection_name="my_collection")
14.Milvus异步操作
- 在Milvus中,为了高性能运作,所以添加或更新数据的操作都是异步非阻塞的,对于刚添加或更新入库的数据,有可能无法立即查询出来。
15.get获取数据
- 返回链接对象后,使用get()方法,获取指定id的数据
- 参数:
- collection_name:集合名称字符串
- ids:为需要获取的id数值或者id数值列表
代码
python
from pymilvus import MilvusClient
from pymilvus.milvus_client import IndexParams
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
client.get(
collection_name="my_collection",
ids=[458476772159659732, 458476772159659737]
)
16.insert写入数据
- 返回链接对象后,使用insert()方法,写入数据
- 参数:
- collection_name:集合名称字符串
- data:插入数据对象。也可以是一个数据对象的列表,同时插入多条数据。
代码
python
from pymilvus import MilvusClient
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
# 创建一个384维的向量(用0填充示例)
search_vector = [0.0] * 384
# 可以设置一些值
search_vector[0] = 0.05
search_vector[1] = 0.23
search_vector[2] = 0.07
search_vector[3] = 0.45
search_vector[4] = 0.13
res1 = client.insert(
collection_name="my_collection",
data={
"vector": search_vector,
"text": "测试22",
"producer": "测试1",
"creator": "测试1",
"creationdate": "测试1",
"title": "测试1",
"author": "测试1",
"moddate": "2022-03-31T00:21:48+08:00",
"source": "测试1",
"total_pages": 1,
"page": 1,
"page_label": "测试1",
},
)
# data可以是:data={[...],[...]}插入多个数据
print(res1)
结果
text
{'insert_count': 1, 'ids': [458490636546304315]}
17.search向量/标量混合查询数据
- 返回链接对象后,使用search()方法,根据向量相似度,查询数据
- 参数:
- collection_name:(字符串,必需)执行搜索的集合的名称。
- data:(列表,必需)包含一个或多个查询向量的列表。每个查询向量的维度必须与集合中向量字段的维度一致。
- limit:(整数,可选)指定要返回的最相似结果的数量。默认值为10。
- filter:(字符串,可选)用于对标量字段进行过滤的表达式。它允许在搜索结果中添加额外的条件。例如:
- 'total_pages > 10'
- 'text == "my_collection"'
- 'producer in "A", "B"'
- 'creationdate >= "2023-01-01"'
- 支持and, or, not等逻辑运算符。也支持使用like
- output_fields:(列表,可选)指定返回标量字段名称的字符串列表。如果不指定,默认不返回任何标量字段。
- search_params:(字典,必需)包含搜索算法特定参数的字典。至少需要包含metric_type。
- "metric_type":(字符串,必需)距离公式类型,必须与集合创建时或索引创建时指定的度量类型一致。常见有"L2","IP","COSINE"。
- "params":(字典,可选)索引搜索参数。取决于使用的索引类型。如:
python
对于IVF_FLAT或IVF_SQ8索引,需要"nprobe"参数,表示在搜索时要探测的聚类数量。
对于HNSW索引,需要"ef"参数,表示搜索的邻居数量。
- consistency_level:(字符串,可选)指定搜索的一致性级别。可选值包括"Strong" , "Bounded" , "Eventually" , "Session"。
- expr:(字符串,可选)用于对结构化数据过滤,也就是只能针对标量数据。类似于SQL中的WHERE子句。它允许在向量相似性搜索的基础上,进一步筛选符合特定条件的记录。(2.x版本以后弃用了,改用filter,功能一样)
- expr能够使用比较运算符如=,逻辑运算符如or,字符串操作如like。
- 被搜索的字符串有特殊字符需要双引号("sci-fi"),其他直接写。
- 字符需要区分大小写。
- timeout:(浮点数,可选)搜索操作的超时时间(秒)。如果搜索超时会抛出异常。默认值为None (不超时)。
- partition_names:(列表,可选)指定搜索的分区的字符串列表。如果未指定,则在所有分区中搜索。
- anns_field:(字符串,可选)如果集合中有多个向量字段,可以指定要执行相似度搜索的向量字段的名称。默认使用集合的第一个向量字段。
代码
python
from pymilvus import MilvusClient
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
# 创建一个384维的向量(用0填充示例)
search_vector = [0.0] * 384
# 可以设置一些值
search_vector[0] = 0.05
search_vector[1] = 0.23
search_vector[2] = 0.07
search_vector[3] = 0.45
search_vector[4] = 0.13
expr = '''
(genre == "sci-fi" OR genre == "action")
AND moddate >= 2010
AND rating > 7.5
AND title LIKE "%Star%"
'''
res = client.search(
collection_name="my_collection",
data=[search_vector],
limit=3,
# filter='name == "测试5" and id > 2',
filter='text == "测试1"',
expr=expr
search_params={"metric_type": "L2", "params": {}},
# output_fields=["pk", "text", "moddate"],
)
for row in res[0]:
print(row)
结果
text
{'id': 458490636546304309, 'distance': 0.0, 'entity': {}}
{'id': 458490636546304311, 'distance': 0.0, 'entity': {}}
# 如果增加了output_fields=["pk", "text", "moddate"]
{'id': 458490636546304309, 'distance': 0.0, 'entity': {'pk': 458490636546304309, 'text': '测试1', 'moddate': '2022-03-31T00:21:48+08:00'}}
{'id': 458490636546304311, 'distance': 0.0, 'entity': {'pk': 458490636546304311, 'text': '测试1', 'moddate': '2022-03-31T00:21:48+08:00'}}
18.query纯标量查询数据
- 返回链接对象后,使用query()方法,查询普通数据
- 参数和search()相似,但没有data参数和anna_field参数。
代码
python
from pymilvus import MilvusClient
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
res = client.query(
collection_name="my_collection",
filter='text == "测试1"',
output_fields=["pk", "text", "moddate"],
)
for row in res[0]:
print(row)
结果
text
{'pk': 458490636546304309, 'text': '测试1', 'moddate': '2022-03-31T00:21:48+08:00'}
{'pk': 458490636546304311, 'text': '测试1', 'moddate': '2022-03-31T00:21:48+08:00'}
19.upsert修改数据
- 返回链接对象后,使用upsert()方法,根据id修改对应内容数据
- 参数
- collection_name(字符串,必需):执行搜索的集合的名称。
- data(列表,必需):包含一个或多个查询向量的列表。为需要修改的数据。
代码
python
from pymilvus import MilvusClient
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
res = client.query(
collection_name="my_collection",
filter='text == "测试1"',
output_fields=["*"] # 返回所有字段
)
row = res[0]
row["moddate"] = "2025-01-01T00:00:00+08:00" # 需要修改的某个字段,其他不变
client.upsert(
collection_name="my_collection",
data=[row]
)
20.delete 删除数据
- 返回链接对象后,使用delete()方法,根据id删除对应内容数据
- 参数
- collection_name(字符串,必需):执行搜索的集合的名称。
- ids(列表,必需):为需要删除数据的id列表。
- filter(字符串,可选):为指定删除数据的数据。ids和filter二选一。
代码
python
from pymilvus import MilvusClient
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
client.delete(
collection_name="my_collection",
ids=[458490636546304309, 458490636546304311]
)
client.delete(
collection_name="my_collection",
filter='text == "xxx"'
)
21.flush数据持久化
- 链接对象操作完后,使用flush()方法,将数据持久化。(非必要操作)
- 作用
- 将内存中的数据持久化到磁盘:强制将指定集合中所有仍在内存缓冲区中的插入、删除或更新操作刷新到磁盘存储。
- 确保数据可见性:在flush操作完成后,新插入的数据将立即可被搜索到。
- 创建新段(segment):Milvus会自动将数据组织成段,flush操作会触发新段的创建。
- 参数
- collection_name(字符串,必需):执行搜索的集合的名称。
代码
python
from pymilvus import MilvusClient
client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
client.insert(
collection_name="my_collection",
data={
"vector": search_vector,
"text": "测试22",
"producer": "测试1",
},
)
client.flush(collection_name="my_collection")
七、Milvus索引性能调优
1.Milvus索引性能调优关键因素:
- 数据规模:向量数量(数据量)越大,索引优化的影响越显著。
- 速度与精度:有些索引(如 FLAT)精度高但查询慢,而ANN(如IVF、HNSW)可加速查询但会牺牲部分精度。
- 内存与存储限制:索引(如HNSW)占用大量内存,而IVF_PQ可降低存储需求。
- 数据分布:如果数据聚类性强,选择合适的索引参数可以提升检索效率。
2.索引类型调优技巧
- FLAT(暴力搜索)
- 适用场景:小规模数据(<100K),需要最高精度的场景,如金融风控、医学影像分析等。
- 特点:进行穷举搜索,不对数据进行压缩,保证100%的召回率和精确性
- 调优技巧:
- 使用GPU加速计算:FLAT搜索是计算密集型任务,启用GPU可以显著提高查询速度。
- 优化并行搜索:可以在客户端或服务端并行处理多个查询,提高吞吐量。
- 如果数据量增长,可以考虑转换为IVF或HNSW以提升搜索效率。
代码
python
index_params.add_index(
field_name="vector",
index_type="FLAT",
metric_type="L2",
params={},
)
- IVF_FLAT(倒排文件索引)
- 适用场景:中等规模数据(>100K),需要平衡查询速度和存储占用,如推荐系统、搜索引擎等。
- 调优技巧:调整 nlist(索引构建时的聚类中心数量):
- nlist越大,索引划分的簇越多,索引构建时间变长,但查询效率提高。
- 经验法则:nlist约为数据集数量的,如1M数据可设nlist=1024。
- 调优技巧:调整 nprobe(搜索时的簇数):
- nprobe越大,搜索范围越广,精度提升但查询速度下降。
- 经验法则:nprobe设为nlist的1%-10%。
代码
python
index_params.add_index(
field_name="vector",
index_type="IVF_FLAT",
metric_type="L2",
params={
"nlist": 1024
}
)
- IVF_SQ8 索引
- 适用场景:相对于IVF_FLAT可加速查询,同时降低存储需求。
- 特点:结合IVF和标量量化(SQ),将每个浮点数(4字节)压缩为1字节,减少内存占用。
- 调优与IVF_FLAT相似
- IVF_PQ 索引
- 适用场景:相对于IVF_FLAT可减少存储占用,但可能牺牲部分精度。
- 特点:结合IVF和乘积量化(PQ),进一步压缩数据存储需求。
- 调优与IVF_FLAT相似
代码
python
index_params.add_index(
field_name="vector",
index_type="IVF_PQ",
metric_type="L2",
params={
"nlist": 128
"m": 4, # 量化因子数
"nbits": 8
}
)
- HNSW(分层导航小世界图)
- 适用场景:高并发、低延迟查询,如AI聊天机器人、实时推荐系统等。
- 调优技巧:调整M(每个节点的最大连接数):
- M越大,索引构建时间增加,但查询精度更高。
- 经验法则:一般设置 M = 16~32。
- 调优技巧:调整efConstruction(索引构建时的搜索范围):
- efConstruction越大,索引质量越好,但构建时间增加。
- 推荐范围:efConstruction = 100~200。
- 调优技巧:调整ef(搜索时的搜索范围):
- ef越大,搜索精度越高,但查询速度变慢。
- 经验法则:ef设置为50~200,适当调整以平衡精度和速度。
代码
python
index_params.add_index(
field_name="vector",
index_type="HNSW",
metric_type="L2",
params={
"M": 16,
"efConstruction": 200
}
)
- SCANN(可扩展最近邻搜索)
- 适用场景:超大规模数据(>10M),存储受限但需要高效搜索,如Google搜索、广告投放等。
- 调优技巧:
- 调整nlist和nprobe,与IVF_FLAT相似,优化搜索范围。
- 使用PCA预处理数据,减少维度,提高搜索速度。
- 结合PQ进行量化,进一步降低存储成本。
代码
python
index_params.add_index(
field_name="vector",
index_type="SCANN",
metric_type="L2",
params={
"nlist": 1024
"reorder_k": 64
}
)
3.其他优化技巧
- 增加查询并发数
- 使用批量查询代替单次查询,减少调用开销。
- 配置Milvus服务器的worker数量,提升处理能力。
代码
python
res = client.search(
collection_name="my_collection",
data=[search_vector],
limit=3,
# filter='name == "测试5" and id > 2',
filter='text == "测试1"',
search_params={"metric_type": "L2", "params": {"nprobe": 32}},
batch_size=100,
)
- 预加载索引,减少I/O开销
- 在大规模数据下,避免频繁加载索引,可以使用Milvus partition功能,将数据拆分成多个分区,仅在需要时加载相关分区。
- 选择合适的距离度量方式
- L2(欧氏距离):适用于标准化数据,如图像、语音特征。
- IP(内积):适用于推荐系统,计算向量相似度。
- COSINE(余弦相似度):适用于文本、自然语言处理任务。
4.选型指南
| 索引类型 | 适用场景 | 精确度 | 查询速度 | 内存需求 |
|---|---|---|---|---|
| FLAT | 小数据集,需 100% 召回 | 100% | 慢 | 高 |
| IVF_FLAT | 大数据集,需较高召回 | 90%+(受nprobe影响) | 快 | 中 |
| IVF_SQ8 | 内存有限,可接受轻微精度损失 | 比IVF_FLAT轻微差距 | 快 | 低 |
| IVF_PQ | 内存有限,可接受较大精度损失 | 比IVF_FLAT较大差距 | 极快 | 极低 |
| SCANN | 高精度,内存充足 | 90%+ | 极快 | 高 |
| HNSW | 高精度,内存充足 | 95%+(受ef影响) | 极极快 | 高 |
5.结论
- 小规模数据(<100K),选择FLAT以获得最高精度。
- 中等规模数据(>100K),使用IVF调优nlist和nprobe以提高查询效率。
- 超大规模数据(>10M),选择SCANN并结合量化优化存储。
- 高并发、低延迟应用,使用HNSW优化M和ef参数。
八、LangChain使用Milvus作向量数据库
1.langchain-milvus库:能够在langchain中使用Milvus向量数据库。
2.需要安装Milvus的LangChain的插件:pip install langchain-milvus
3.创建向量数据库对象
- 使用Milvus()方法,创建一个向量数据库对象
- 参数:
- embedding_function:嵌入模型对象
- connection_args:连接Milvus服务器的配置参数字典,有:
- uri: Milvus服务器地址字符串 (如 "http://localhost:19530")
- token: 认证令牌 (如果启用认证)
- secure: 布尔值,是否使用安全连接
- user:用户名(如果需要)
- password:密码(如果需要)
- db_name:选用(或创建)数据库名(如果需要)
- collection_name:要创建或连接的集合名字符串
- drop_old:当集合已存在时是否先删除旧集合再创建新集合,默认False
- auto_id:是否自动生成主键ID,默认True
- consistency_level:设置集合的一致性级别字符串,可选值:"Strong", "Session"(默认), "Bounded", "Eventually", "Customized"
- index_params:创建集合时,配置向量索引的参数字典,有:
- index_type: 索引类型 (如 "FLAT", "IVF_FLAT", "HNSW" 等)
- metric_type: 相似度度量方式 ("L2", "IP", "COSINE")
- params: 特定索引类型的参数
- search_params:搜索集合时的参数配置字典
- metric_type: 相似度度量方式 ("L2", "IP", "COSINE")
- params: 特定索引类型的参数
- 定义字段名称参数:一般情况下会默认定义了3个必有的字段,和其他字段
- primary_field:定义主键字段名,默认"pk"
- text_field:定义存储原始文本的字段名,默认"text"
- vector_field:存储向量的字段名,默认"vector"
- fields:定义其他字段列表(如元数据字段)默认None
- 返回向量数据库对象
4.向量数据库对象增加数据
- 返回向量数据库对象后,使用add_documents()方法,增加document列表。
- 参数document为document列表
5.创建检索器对象
- 返回向量数据库对象后,使用as_retriever()方法,返回向量数据库检索器对象retriever。
6.自动新建标量字段
- 在document对象中,可能会存在metadata的字典数据。Milvus会自动地为metadata里地每个元素创建一个字段,并保存。
- 搜索时,可以使用标量字段作结构化过滤,如year > 2010
7.示例
代码
python
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_openai import ChatOpenAI
from langchain_milvus import Milvus
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_community.document_loaders import UnstructuredMarkdownLoader
from operator import itemgetter
from langchain_text_splitters import MarkdownTextSplitter
# 初始化 LLM和嵌入模型
llm = ChatOpenAI(
model="Pro/deepseek-ai/DeepSeek-V3",
openai_api_key="************",
openai_api_base="https://api.siliconflow.cn/v1",
temperature=0.5,
max_tokens=8000,
)
embeddings = HuggingFaceEmbeddings(
model_name="D:/python/envs/lc/hfmodel/sentence-transformers/all-MiniLM-L6-v2",
)
# document块列表
loader = UnstructuredMarkdownLoader(file_path="output/c3.md")
documents = loader.load()
splitter = MarkdownTextSplitter(
chunk_size=1000,
chunk_overlap=200,
)
split_documents = splitter.split_documents(documents)
# 向量数据库,增加数据
vectorstore = Milvus(
embedding_function=embeddings,
connection_args={"uri": "http://192.168.1.101:19530"},
collection_name="mt_coll",
drop_old=True,
auto_id=True,
index_params={
"index_type": "FLAT",
"metric_type": "L2",
"params": {"nlist": 1024},
},
search_params={"metric_type": "L2", "params": {"nprobe": 100}},
)
vectorstore.add_documents(split_documents)
# 提示模板
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"根据上下文和对话历史回答问题。不知道的问题直接回答不知道。",
),
MessagesPlaceholder(variable_name="chat_history"),
(
"human",
"""上下文:{context}。 问题:{question}。 回答:""",
),
]
)
# 格式化文档函数
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
# 创建基础RAG链
rag_chain = (
{
"context": itemgetter("question")
| vectorstore.as_retriever(search_kwargs={"k": 2})
| format_docs,
"question": itemgetter("question"),
"chat_history": itemgetter("chat_history") | RunnablePassthrough(),
}
| prompt
| llm
| StrOutputParser()
)
# 会话历史存储
store = {}
def get_session_history(session_id: str) -> ChatMessageHistory:
if session_id not in store:
store[session_id] = ChatMessageHistory()
return store[session_id]
# 使用RunnableWithMessageHistory包装RAG链
chain_with_history = RunnableWithMessageHistory(
runnable=rag_chain,
get_session_history=get_session_history,
input_messages_key="question",
history_messages_key="chat_history",
)
# 模拟对话
session_id = "user_123"
q1 = "茅台的产品介绍"
q2 = "控制面板上的Shutdown Faults,是什么故障,如何处理"
# 第一次查询
response = chain_with_history.invoke(
{"question": q1},
config={"configurable": {"session_id": session_id}},
)
print(f"Q: {q1}\nA: {response}")
# 第二次查询(依赖对话历史)
response = chain_with_history.invoke(
{"question": q2},
config={"configurable": {"session_id": session_id}},
)
print(f"Q: {q2}\nA: {response}")
总结
本文整理了 Milvus 向量数据库的核心概念、部署方式、基础操作、集合与字段设计、索引创建、数据插入、向量搜索和标量查询等内容。实际项目中,Milvus 适合用于大规模向量检索、RAG 知识库、多模态检索和语义搜索等场景;在使用时需要重点关注向量维度、索引类型、metric_type、集合加载状态、过滤条件以及数据持久化等关键配置。