| 大家好,我是工藤学编程 🦉 | 一个正在努力学习的小博主,期待你的关注 |
|---|---|
| 实战代码系列最新文章😉 | C++实现图书管理系统(Qt C++ GUI界面版) |
| SpringBoot实战系列🐷 | 【SpringBoot实战系列】SpringBoot3.X 整合 MinIO 存储原生方案 |
| 分库分表 | 分库分表之实战-sharding-JDBC分库分表执行流程原理剖析 |
| 消息队列 | 深入浅出 RabbitMQ-RabbitMQ消息确认机制(ACK) |
| AI大模型 | 零基础学AI大模型之Milvus索引实战 |
前情摘要
1、零基础学AI大模型之读懂AI大模型
2、零基础学AI大模型之从0到1调用大模型API
3、零基础学AI大模型之SpringAI
4、零基础学AI大模型之AI大模型常见概念
5、零基础学AI大模型之大模型私有化部署全指南
6、零基础学AI大模型之AI大模型可视化界面
7、零基础学AI大模型之LangChain
8、零基础学AI大模型之LangChain六大核心模块与大模型IO交互链路
9、零基础学AI大模型之Prompt提示词工程
10、零基础学AI大模型之LangChain-PromptTemplate
11、零基础学AI大模型之ChatModel聊天模型与ChatPromptTemplate实战
12、零基础学AI大模型之LangChain链
13、零基础学AI大模型之Stream流式输出实战
14、零基础学AI大模型之LangChain Output Parser
15、零基础学AI大模型之解析器PydanticOutputParser
16、零基础学AI大模型之大模型的"幻觉"
17、零基础学AI大模型之RAG技术
18、零基础学AI大模型之RAG系统链路解析与Document Loaders多案例实战
19、零基础学AI大模型之LangChain PyPDFLoader实战与PDF图片提取全解析
20、零基础学AI大模型之LangChain WebBaseLoader与Docx2txtLoader实战
21、零基础学AI大模型之RAG系统链路构建:文档切割转换全解析
22、零基础学AI大模型之LangChain 文本分割器实战:CharacterTextSplitter 与 RecursiveCharacterTextSplitter 全解析
23、零基础学AI大模型之Embedding与LLM大模型对比全解析
24、零基础学AI大模型之LangChain Embedding框架全解析
25、零基础学AI大模型之嵌入模型性能优化
26、零基础学AI大模型之向量数据库介绍与技术选型思考
27、零基础学AI大模型之Milvus向量数据库全解析
28、零基础学AI大模型之Milvus核心:分区-分片-段结构全解+最佳实践
29、零基础学AI大模型之Milvus部署架构选型+Linux实战:Docker一键部署+WebUI使用
30、零基础学AI大模型之Milvus实战:Attu可视化安装+Python整合全案例
31、零基础学AI大模型之Milvus索引实战
本文章目录
- [零基础学AI大模型之Milvus DML实战](#零基础学AI大模型之Milvus DML实战)
-
- 一、DML核心概念:Milvus数据操作的基础认知
-
- [1. 什么是Milvus的DML操作?](#1. 什么是Milvus的DML操作?)
- [2. 关键前置概念](#2. 关键前置概念)
- 二、实战准备:环境搭建与连接验证
-
- [1. 环境要求](#1. 环境要求)
- [2. 环境搭建与连接](#2. 环境搭建与连接)
- 三、DML全流程实战(Python+Attu双视角)
-
- [1. 前置步骤:创建集合(数据存储载体)](#1. 前置步骤:创建集合(数据存储载体))
- [2. 核心操作1:插入数据(Insert)](#2. 核心操作1:插入数据(Insert))
- [3. 核心操作2:删除数据(Delete)](#3. 核心操作2:删除数据(Delete))
- [4. 核心操作3:更新数据(Update)](#4. 核心操作3:更新数据(Update))
- [5. 补充操作:加载/释放集合(关键前提)](#5. 补充操作:加载/释放集合(关键前提))
- 四、关键注意事项与避坑指南
-
- [1. 必踩坑1:未加载集合导致操作失败](#1. 必踩坑1:未加载集合导致操作失败)
- [2. 必踩坑2:主键冲突](#2. 必踩坑2:主键冲突)
- [3. 必踩坑3:向量维度不匹配](#3. 必踩坑3:向量维度不匹配)
- [4. 批量插入最佳实践](#4. 批量插入最佳实践)
- [5. 删除操作避坑](#5. 删除操作避坑)
零基础学AI大模型之Milvus DML实战
一、DML核心概念:Milvus数据操作的基础认知
1. 什么是Milvus的DML操作?
DML(Data Manipulation Language)即数据操纵语言,在Milvus中核心包括数据插入(Insert)、删除(Delete)、更新(Update) 三类操作,是与数据直接交互的核心手段。
2. 关键前置概念
- 集合(Collection):Milvus中数据存储的基本单位,类似关系型数据库的"表",所有DML操作都基于集合展开;
- 动态字段:
enable_dynamic_field=True时,无需在Schema中预定义的字段可直接随数据插入,灵活适配多变数据场景; - 自动主键:
auto_id=True时,Milvus会自动生成唯一主键(INT64类型),无需手动指定,避免主键冲突; - 数据加载:无论是Attu可视化操作还是Python查询/删除,都需先将集合"加载到内存"(load),否则无法执行核心操作。
二、实战准备:环境搭建与连接验证
1. 环境要求
- Milvus服务:已部署(本地/远程,版本2.5X),网络可通;
- PyMilvus:版本2.5.5(与Milvus版本匹配);
- Attu:已安装(可选,用于可视化验证操作结果)。
2. 环境搭建与连接
bash
# 安装PyMilvus(若未安装)
pip install pymilvus==2.5.5
python
# Python连接Milvus服务(核心代码,后续操作均基于此连接)
from pymilvus import MilvusClient, DataType
# 实例化客户端,连接远程Milvus服务(替换为你的服务地址)
client = MilvusClient(uri="http://192.168.229.128:19530")
# 验证连接(列出所有数据库,无报错则连接成功)
databases = client.list_databases()
print("当前Milvus数据库列表:", databases) # 输出:['default', ...]
三、DML全流程实战(Python+Attu双视角)
1. 前置步骤:创建集合(数据存储载体)
集合是DML操作的基础,需先定义Schema(字段结构)和索引,再创建集合。
Python实战代码
python
# 步骤1:定义Schema(字段结构)
schema = client.create_schema(
auto_id=False, # 关闭自动主键,手动指定ID(也可设为True自动生成)
enable_dynamic_field=True # 开启动态字段,支持灵活扩展
)
# 添加字段(主键字段+向量字段,动态字段无需预定义)
schema.add_field(
field_name="id",
datatype=DataType.INT64,
is_primary=True # 主键字段(必须唯一,不可为向量类型)
)
schema.add_field(
field_name="vector",
datatype=DataType.FLOAT_VECTOR,
dim=128 # 向量维度(需与实际插入数据一致,如768维BERT向量)
)
# 验证Schema合法性(避免字段定义错误)
schema.verify()
# 步骤2:定义索引参数(向量字段需创建索引,否则查询低效)
index_params = client.prepare_index_params()
index_params.add_index(
field_name="vector", # 索引字段(向量字段)
index_type="IVF_FLAT", # 索引类型(中大数据量首选,性价比高)
metric_type="L2", # 距离度量方式(欧氏距离)
params={"nlist": 1024} # 索引参数(聚类中心数,建议sqrt(数据量))
)
# 步骤3:创建集合(集合名自定义,需唯一)
client.create_collection(
collection_name="dml_demo_collection", # 集合名
schema=schema, # 字段结构
index_params=index_params # 索引配置
)
print("集合创建成功!")
Attu可视化验证
- 启动Attu,连接Milvus服务;
- 在左侧导航栏找到"Collections",即可看到新建的
dml_demo_collection集合,状态为"Unloaded"(未加载)。

2. 核心操作1:插入数据(Insert)
支持单条插入 和批量插入,批量插入更高效(推荐大数据量场景使用)。
(1)Python实战:单条/批量插入
python
# 场景1:单条数据插入
single_data = {
"id": 1,
"vector": [0.1]*128, # 128维向量(简化为全0.1,实际需替换为真实向量)
"text": "这是第一条测试数据", # 动态字段(未预定义,直接插入)
"category": "test" # 动态字段(灵活扩展)
}
# 单条插入
single_insert_result = client.insert(
collection_name="dml_demo_collection",
data=single_data
)
print("单条插入成功,主键ID:", single_insert_result["ids"]) # 输出:[1]
# 场景2:批量数据插入(推荐,效率更高)
batch_data = [
{"id": 2, "vector": [0.2]*128, "text": "批量插入-测试数据2", "category": "test"},
{"id": 3, "vector": [0.3]*128, "text": "批量插入-测试数据3", "category": "formal"},
{"id": 4, "vector": [0.4]*128, "text": "批量插入-测试数据4", "category": "formal"}
]
# 批量插入
batch_insert_result = client.insert(
collection_name="dml_demo_collection",
data=batch_data
)
print("批量插入成功,主键ID列表:", batch_insert_result["ids"]) # 输出:[2,3,4]
(2)批量插入最佳实践
- 批次大小:每批插入10万~100万条数据(平衡效率与内存占用);
- 数据格式:确保向量维度与Schema中
dim一致,主键唯一; - 动态字段:无需预定义,直接随数据插入,适用于非固定字段场景(如日志、多维度标签)。
(3)Attu可视化验证插入结果
- 选中
dml_demo_collection集合,点击"Load"(加载到内存); - 点击"Browse Data",即可看到所有插入的数据(包括预定义字段和动态字段)。

3. 核心操作2:删除数据(Delete)
支持按主键删除 和按条件删除两种方式,删除后数据不可恢复,需谨慎操作。
Python实战代码
python
# 场景1:按主键删除(精准删除,推荐优先使用)
delete_ids = [1, 2] # 要删除的主键ID列表
client.delete(
collection_name="dml_demo_collection",
ids=delete_ids
)
print(f"主键ID为{delete_ids}的数据已删除")
# 场景2:按条件删除(灵活筛选,支持标量字段/动态字段过滤)
# 示例:删除category为"formal"且text包含"测试"的数据
client.delete(
collection_name="dml_demo_collection",
filter='category == "formal" and text like "%测试%"' # 过滤条件(类似SQL语法)
)
print('category为"formal"且text包含"测试"的数据已删除')
关键说明
- 条件语法:支持
==、!=、>、<、like、in等运算符,仅支持标量字段(含动态标量字段)过滤; - 向量字段:不支持直接作为过滤条件删除;
- 可视化验证:Attu中"Browse Data"刷新后,可看到删除后的数据残留(仅剩余未被删除的记录)。

4. 核心操作3:更新数据(Update)
Milvus不支持直接更新数据 (无update方法),需通过"删除旧数据+插入新数据"的组合方式实现更新。
Python实战代码
python
# 需求:更新主键ID=3的数据(vector和text字段)
old_id = 3 # 要更新的旧数据主键ID
# 步骤1:删除旧数据
client.delete(
collection_name="dml_demo_collection",
ids=[old_id]
)
print(f"主键ID={old_id}的旧数据已删除")
# 步骤2:插入新数据(复用旧主键ID,实现"更新"效果)
updated_data = {
"id": old_id, # 保持主键ID不变
"vector": [0.35]*128, # 新的向量值
"text": "更新后的测试数据3", # 新的文本内容
"category": "formal", # 保留原有的动态字段值
"update_time": "2024-01-01" # 新增动态字段(更新时间)
}
client.insert(
collection_name="dml_demo_collection",
data=updated_data
)
print(f"主键ID={old_id}的数据已更新完成")
更新操作注意事项
- 主键复用:更新时需使用原主键ID,确保数据唯一性;
- 动态字段:可新增/修改动态字段值,无需额外配置;
- 效率考量:大数据量更新场景(如批量更新10万条),建议分批次执行"删除+插入",避免单次操作压力过大。
5. 补充操作:加载/释放集合(关键前提)
无论是Python查询、删除,还是Attu可视化操作,都需先将集合"加载到内存",操作完成后可释放内存(优化资源占用)。
python
# 加载集合到内存(查询/删除前必须执行)
client.load_collection(collection_name="dml_demo_collection")
print("集合加载成功,可执行查询/删除操作")
# 释放集合内存(操作完成后执行,节省资源)
client.release_collection(collection_name="dml_demo_collection")
print("集合已释放内存")
四、关键注意事项与避坑指南
1. 必踩坑1:未加载集合导致操作失败
- 现象:Python执行删除/查询时提示"collection not loaded";Attu操作时提示"collection is unloaded";
- 原因:集合未加载到内存,Milvus无法访问数据;
- 解决方案:操作前执行
load_collection,操作完成后可执行release_collection释放内存。
2. 必踩坑2:主键冲突
- 现象:插入数据时提示"primary key duplicate";
- 原因:
auto_id=False时,手动指定的主键ID已存在; - 解决方案:开启
auto_id=True自动生成主键,或插入前校验ID唯一性。
3. 必踩坑3:向量维度不匹配
- 现象:插入数据时提示"vector dim mismatch";
- 原因:插入向量的维度与Schema中
dim定义不一致(如Schema设128维,实际插入768维); - 解决方案:插入前校验向量维度,确保与Schema完全一致。
4. 批量插入最佳实践
- 批次大小:每批10万~100万条,避免单次插入过多导致超时;
- 数据格式:动态字段仅支持标量类型(字符串、数值等),不支持嵌套结构;
- 错误处理:插入时若部分数据失败,可通过
insert_result["insert_count"]查看成功条数,失败数据需单独处理。
5. 删除操作避坑
- 条件删除:仅支持标量字段(含动态标量字段),不支持向量字段过滤;
- 不可恢复:删除后数据无法恢复,建议操作前备份关键数据;
- 索引影响:删除数据后,索引不会自动更新,数据变更超过30%时需重建索引(保证查询精度)。