一文搞懂Milvus:从基本概念到Schema定义、向量搜索全解析

张开发
2026/4/22 18:44:48 15 分钟阅读

分享文章

一文搞懂Milvus:从基本概念到Schema定义、向量搜索全解析
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 应用中被广泛使用。同时它还提供了丰富的 SDKPython、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 SDKlangchain-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 集合 CollectionsCollections 是 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中的示例为例先定义一个 Schema1 def define_schema():2 schema MilvusClient.create_schema(enable_dynamic_fieldTrue)3 schema.add_field(field_nameid, datatypeDataType.INT64,4 auto_idTrue, is_primaryTrue, description主键)5 schema.add_field(field_nametitle, datatypeDataType.VARCHAR,6 max_length512, description新闻标题)7 schema.add_field(field_nametitle_vector, datatypeDataType.FLOAT_VECTOR,8 dim5, description标题向量)9 schema.add_field(field_namecreate_time, datatypeDataType.INT32, description创建时间)10 return schema1112if __name__ __main__:13 client MilvusClient(./milvus_demo.db)14 schema define_schema()这里有一个参数值得特别说明。第2行中的enable_dynamic_fieldTrue的作用是当我们实际插入的数据中包含 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_nametitle_vector, index_typeAUTOINDEX,3 metric_typeIP)第2~3行声明了将要为title_vector字段构建索引。index_typeAUTOINDEX会在建立索引时自动分析 Collection 中的数据分布并选择最优的索引参数在搜索性能和准确性之间取得平衡。metric_type则是指定相似度的度量方式几种常见选项的区别如下类型是否考虑向量长度适合场景L2是欧式距离IP是推荐系统、embeddingCOSINE否只看方向文本相似度本文示例中使用的是IP向量内积。主要考虑到在 RAG 场景中Embedding 模型输出的向量通常已经过归一化处理此时 IP 和 COSINE 的效果非常接近但 IP 的计算速度更快因此是一个更实用的默认选择。完成 Schema 及索引定义以后通过如下语句创建 Collection1 client.create_collection(collection_namemy_collection, schemaschema, index_paramsindex_params)创建完成后可以通过如下代码查看当前库中的所有 Collection1 res client.list_collections()2 print(res) # [my_collection]4.3 插入数据由于上面指定了auto_idTrue插入数据时不需要手动指定 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_namemy_collection, datadata)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_namemy_collection)3 print(f加载状态{client.get_load_state(collection_namemy_collection)})4 # 条件查询5 res client.query(collection_namemy_collection, filterid 0,6 output_fields[title, create_time])6 print(f查询结果: {res})7 # 通过动态字段过滤8 res client.query(collection_namemy_collection, filterauthor wangcheng)9 print(f动态字段查询结果: {res})10 client.release_collection(collection_namemy_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_namemy_collection)3 query_vector [0.81, 0.45, 0.51, 0.26, 0.66]4 res client.search(collection_namemy_collection,5 anns_fieldtitle_vector,6 data[query_vector],7 limit3,8 search_params{metric_type: IP})9 print(res)10 client.release_collection(collection_namemy_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%免费】

更多文章