1 向量数据库选择
1.1 常见向量数据库
目前市面上可供选择的向量数据库有很多,例如 Chroma、Milvus、MongoDB、pgvector、Qdrant 等等。整体来看,它们可以分成两大类:
- 专门的向量数据库:Milvus、Qdrant、Chroma,从底层就是为向量检索而设计的
- 通用数据库 + 向量扩展:MongoDB、PostgreSQL + pgvector,在原有数据库能力上叠加了向量检索支持
两类方案各有适用场景,对于专注于 RAG 开发、对检索性能有一定要求的场景,专门的向量数据库通常是更合适的选择。
1.2 为什么选择 Milvus
这里我们以使用最为广泛之一的 Milvus /ˈmɪl.vəs/(米尔沃斯)为例来进行介绍。Milvus 这个词原意是鹰科中的一种猛禽,以飞行速度快、视力敏锐、适应性强而著称,而这也恰好能凸显它作为向量数据库时的优秀性能。

图 1. Milvus 采用者
从图1可以看到,Salesforce、PayPal、eBay 等大量知名企业都是 Milvus 的使用者,这也从侧面说明了它在生产环境中的可靠性。
Milvus 是一个开源的向量数据库,用于管理、索引和搜索高维向量数据,在机器学习、推荐系统和生成式 AI 应用中被广泛使用。同时,它还提供了丰富的 SDK(Python、Java、Go 等),能够与 AI 框架(如 PyTorch、TensorFlow、OpenAI Embeddings API)快速集成。
1.3 部署模式选择
Milvus 提供了三种部署模式,覆盖从本地原型开发到大规模生产部署的各类场景:
- Milvus Lite:一个轻量级 Python 库,可以直接集成到应用程序中,非常适合在 Jupyter Notebook 中进行快速原型开发,或在资源有限的设备上运行
- Milvus Standalone:单机服务器部署,所有组件打包在一个 Docker 镜像中,部署简单
- Milvus Distributed:部署在 Kubernetes 集群上,采用云原生架构,专为十亿规模甚至更大的场景设计
在实际项目中,部署模式的选择主要取决于数据规模,如图2所示。

图 2. Milvus 版本选择
总结起来就是:Milvus Lite 建议用于百万级以内的向量规模;Milvus Standalone 可扩展至约一亿规模;Milvus Distributed 则是专为一亿到数百亿规模的大规模部署而设计的。
后续我们将以 Milvus Lite 为例来进行介绍。
2 环境安装
对于本门课程所使用的 RAG 环境,需要依次安装以下三个包:
pip install milvus-litepip install pymilvuspip install langchain-milvus
其中 milvus-lite 是核心库,pymilvus 是对应的 Python SDK,langchain-milvus 是为了后续在 LangChain 框架中使用 Milvus 而需要安装的集成包。
安装完成以后,可以通过如下方式来创建一个向量数据库文件:
1 from pymilvus import MilvusClient2 client = MilvusClient("./milvus_demo.db")
运行上述代码后,将在当前目录下生成名为 milvus_demo.db 的数据库文件,后续所有数据都会持久化存储在这个文件中。
3 基本概念
在动手操作之前,我们先来了解一下 Milvus 中几个重要的基本概念。理解这些概念的最简单方式,就是把它们和我们熟悉的关系型数据库(如 MySQL)做一个映射对比。
在关系型数据库中,我们习惯用 CRUD(增删改查)来描述数据操作,其本质是基于字段条件的精确匹配;而向量数据库同样有类似的"增删改查"逻辑,核心区别在于它的"查"不是等值匹配,而是相似度搜索。
3.1 数据库
与传统关系型数据库一样,Milvus 中的数据库是组织和管理数据的逻辑单元,可以创建多个数据库来实现多租户隔离。不过值得注意的是,Milvus Lite 不支持创建多个数据库,只含有一个默认数据库,这一点在使用时需要留意。
3.2 集合 Collections
Collections 是 Milvus 中最核心的数据组织单元,类似于关系型数据库中的表。Collection 是一个二维结构,具有固定的列和变化的行,每列代表一个字段,每行代表一个实体(Entity)。

图 3. Collection 中的实体和字段
如图3所示,这个 Collection 一共有4列和5个实体。
3.3 Schema 和字段
在创建 Collection 之前,我们需要先定义一个 Schema,用于描述这个 Collection 有哪些字段、每个字段的数据类型是什么。可以把 Schema 理解为关系型数据库中的建表语句。
同时,与关系型数据库中的主键类似,Collection 也有一个主字段(Primary Key)用于唯一标识每条记录,通常会将其设置为自增。
3.4 加载与释放
这是 Milvus 中一个与传统数据库差异比较大的概念。在 Milvus 中,执行相似度搜索之前需要先将 Collection 加载到内存中,Milvus 会将所有索引文件和字段的原始数据一并载入,以保证搜索响应速度。
在实际使用中,大多数情况下在服务启动时加载好 Collection 然后持续使用即可,不需要频繁地加载和释放。如果有多个 Collection 且内存不够全部加载,可以只保留热门 Collection 在内存中,手动释放冷门的 Collection 以节省资源。
4 Milvus 使用示例
介绍完基本概念以后,我们来看一下如何完成 Collection 的创建及基本的增删改查操作。
4.1 Schema 定义
我们以图3中的示例为例,先定义一个 Schema:
1 def define_schema():2 schema = MilvusClient.create_schema(enable_dynamic_field=True)3 schema.add_field(field_name="id", datatype=DataType.INT64,4 auto_id=True, is_primary=True, description='主键')5 schema.add_field(field_name="title", datatype=DataType.VARCHAR,6 max_length=512, description="新闻标题")7 schema.add_field(field_name="title_vector", datatype=DataType.FLOAT_VECTOR,8 dim=5, description="标题向量")9 schema.add_field(field_name="create_time", datatype=DataType.INT32, description="创建时间")10 return schema1112if __name__ == '__main__':13 client = MilvusClient("./milvus_demo.db")14 schema = define_schema()
这里有一个参数值得特别说明。第2行中的 enable_dynamic_field=True 的作用是:当我们实际插入的数据中包含 Schema 未声明的字段时,Milvus 不会直接报错,而是会自动创建一个隐藏字段 $meta,将所有未声明的字段以 JSON 结构存入其中。
例如上面我们只声明了4个字段,如果插入数据时多带了两个字段 "author": "wang", "score": 98,实际存储形式会变成:
{ id: 10, title: "xxxxxxxx", title_vector: [...], create_time: 2026-02-22, $meta: { "author": "wang", "score": 98 }}
如果不开启这个选项,插入含有未声明字段的数据时就会报错 field extra_field not found in schema。
这里还有一点需要注意:schema 只是一个包含结构定义的 Python 对象,它本身不会单独存在于数据库中,真正持久化的是基于这个 schema 创建的 Collection。
4.2 索引及 Collection 创建
为了能够快速搜索到目标向量,在创建 Collection 之前还需要声明索引:
1 index_params = client.prepare_index_params()2 index_params.add_index(field_name="title_vector", index_type="AUTOINDEX",3 metric_type="IP")
第2~3行声明了将要为 title_vector 字段构建索引。index_type="AUTOINDEX" 会在建立索引时自动分析 Collection 中的数据分布,并选择最优的索引参数,在搜索性能和准确性之间取得平衡。metric_type 则是指定相似度的度量方式,几种常见选项的区别如下:
| 类型 | 是否考虑向量长度 | 适合场景 |
|---|---|---|
| L2 | 是 | 欧式距离 |
| IP | 是 | 推荐系统、embedding |
| COSINE | 否(只看方向) | 文本相似度 |
本文示例中使用的是 IP(向量内积)。主要考虑到在 RAG 场景中,Embedding 模型输出的向量通常已经过归一化处理,此时 IP 和 COSINE 的效果非常接近,但 IP 的计算速度更快,因此是一个更实用的默认选择。
完成 Schema 及索引定义以后,通过如下语句创建 Collection:
1 client.create_collection(collection_name="my_collection", schema=schema, index_params=index_params)
创建完成后,可以通过如下代码查看当前库中的所有 Collection:
1 res = client.list_collections()2 print(res) # ['my_collection']
4.3 插入数据
由于上面指定了 auto_id=True,插入数据时不需要手动指定 id 字段,Milvus 会自动生成,这一点与传统关系型数据库的行为一致。示例代码如下:
1 def insert_data(client):2 dt0 = datetime.datetime.strptime("2026-03-01", "%Y-%m-%d")3 dt1 = datetime.datetime.strptime("2026-02-28", "%Y-%m-%d")4 data = [5 {"title": "谷歌AI攻克6道世界级难题!", 6 "title_vector": [0.02, 0.05, 0.12, 0.33, 0.26],7 "create_time": int(dt0.timestamp())},8 {"title": "用AI替代人类,Block裁员四成",9 "title_vector": [0.23, 0.15, 0.32, 0.09, 0.25],10 "create_time": int(dt1.timestamp())},11 # ... 其余数据12 ]13 res = client.insert(collection_name="my_collection", data=data)14 print("Generated IDs:", res)
运行结束后,将看到类似如下输出:
Generated IDs: {'insert_count': 5, 'ids': [464611230885871616, 464611230885871617, ...]}
这里有一个有意思的细节:Milvus 自动生成的主键并不是简单的自增整数,而是分布式的全局唯一 ID。为什么不能用简单自增呢?设想一下,如果节点 A 和节点 B 同时插入数据,两个节点都从 0 开始自增,那么就必然会产生冲突。所以 Milvus 的 ID 不是严格连续递增的,大家在使用时不要依赖 ID 的连续性来做业务逻辑。
4.4 查询数据
在查询数据之前,需要先将 Collection 加载到内存中:
1 def select_data(client):2 client.load_collection(collection_name="my_collection")3 print(f"加载状态:{client.get_load_state(collection_name='my_collection')}")4 # 条件查询5 res = client.query(collection_name="my_collection", filter="id >= 0",6 output_fields=["title", "create_time"])6 print(f"查询结果: {res}")7 # 通过动态字段过滤8 res = client.query(collection_name="my_collection", filter="author == 'wangcheng'")9 print(f"动态字段查询结果: {res}")10 client.release_collection(collection_name="my_collection")
第5行中的 filter 参数类似于传统数据库的 WHERE 子句,查询时必须指定。第8行是通过动态字段进行过滤,也可以写成 filter="$meta['author'] == 'wangcheng'" 的显式形式,两种写法效果一致。
这里需要补充说明一点:在 Milvus Lite 中,load_collection 这个操作实际上已经被框架内部接管了,即使不手动调用也能正常查询。但为了保持代码在不同部署模式下的兼容性,建议还是显式加上这一步。
4.5 搜索数据
相似度搜索才是向量数据库最核心的能力——给定一个查询向量,返回与之最相似的前 K 个向量:
1 def search_data(client):2 client.load_collection(collection_name="my_collection")3 query_vector = [0.81, 0.45, 0.51, 0.26, 0.66]4 res = client.search(collection_name="my_collection",5 anns_field="title_vector",6 data=[query_vector],7 limit=3,8 search_params={"metric_type": "IP"})9 print(res)10 client.release_collection(collection_name="my_collection")
上述代码返回与 query_vector 最相似的前3个结果。这里需要注意,第8行指定的 metric_type 必须与创建索引时使用的 metric_type 保持一致,否则会出现预期外的结果。
运行结束后,可以看到类似如下输出:
data: [[{'id': 464611230885871619, 'distance': 1.76010000705719, 'entity': {}}, {'id': 464611230885871620, 'distance': 1.102099895477295, 'entity': {}}, {'id': 464611230885871617, 'distance': 0.6053999662399292, 'entity': {}}]]
返回结果中的 distance 字段就是相似度得分,当使用 IP(内积)度量时,值越大表示越相似。大家有兴趣可以对照上面插入的数据,验证一下搜索结果的排序是否符合预期。
以上完整示例代码可参见 Code/Chapter03/C09_milvus_usage.py 文件。
到此,我们就把 Milvus 的安装方法和基本使用方式介绍完了。大家在实际项目中会倾向于选择哪种部署模式,或者在安装和使用过程中遇到了什么问题,欢迎在评论区聊聊。在下一节内容中,我们将介绍如何在 LangChain 中接入 Milvus,真正把向量存储环节整合进 RAG 的开发流程中。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】


2656

被折叠的 条评论
为什么被折叠?



