大家好,我是工藤学编程 🦉 | 一个正在努力学习的小博主,期待你的关注 |
|---|---|
实战代码系列最新文章😉 | 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索引实战
DML(Data Manipulation Language)即数据操纵语言,在Milvus中核心包括数据插入(Insert)、删除(Delete)、更新(Update) 三类操作,是与数据直接交互的核心手段。
enable_dynamic_field=True时,无需在Schema中预定义的字段可直接随数据插入,灵活适配多变数据场景;auto_id=True时,Milvus会自动生成唯一主键(INT64类型),无需手动指定,避免主键冲突;# 安装PyMilvus(若未安装)
pip install pymilvus==2.5.5# 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操作的基础,需先定义Schema(字段结构)和索引,再创建集合。
# 步骤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("集合创建成功!")dml_demo_collection集合,状态为“Unloaded”(未加载)。

支持单条插入和批量插入,批量插入更高效(推荐大数据量场景使用)。
# 场景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]dim一致,主键唯一;dml_demo_collection集合,点击“Load”(加载到内存);
支持按主键删除和按条件删除两种方式,删除后数据不可恢复,需谨慎操作。
# 场景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等运算符,仅支持标量字段(含动态标量字段)过滤;
Milvus不支持直接更新数据(无update方法),需通过“删除旧数据+插入新数据”的组合方式实现更新。
# 需求:更新主键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}的数据已更新完成")无论是Python查询、删除,还是Attu可视化操作,都需先将集合“加载到内存”,操作完成后可释放内存(优化资源占用)。
# 加载集合到内存(查询/删除前必须执行)
client.load_collection(collection_name="dml_demo_collection")
print("集合加载成功,可执行查询/删除操作")
# 释放集合内存(操作完成后执行,节省资源)
client.release_collection(collection_name="dml_demo_collection")
print("集合已释放内存")load_collection,操作完成后可执行release_collection释放内存。auto_id=False时,手动指定的主键ID已存在;auto_id=True自动生成主键,或插入前校验ID唯一性。dim定义不一致(如Schema设128维,实际插入768维);insert_result["insert_count"]查看成功条数,失败数据需单独处理。