零基础学AI大模型之Milvus向量Search查询综合案例实战

大家好,我是工藤学编程 🦉 一个正在努力学习的小博主,期待你的关注
实战代码系列最新文章😉 C++实现图书管理系统(Qt C++ GUI界面版)
SpringBoot实战系列🐷 【SpringBoot实战系列】SpringBoot3.X 整合 MinIO 存储原生方案
分库分表 分库分表之实战-sharding-JDBC分库分表执行流程原理剖析
消息队列 深入浅出 RabbitMQ-RabbitMQ消息确认机制(ACK)
AI大模型 零基础学AI大模型之Milvus DML实战

前情摘要

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索引实战
32、零基础学AI大模型之Milvus DML实战

本文章目录

零基础学AI大模型之Milvus向量Search查询综合案例实战

一、实战核心目标

  1. 掌握混合数据类型(标量+向量)集合的创建方法
  2. 实现结构化+非结构化数据的批量插入
  3. 精通带过滤条件的向量混合查询(核心重点)
  4. 理解Milvus Search语法核心参数与使用场景
  5. 验证向量搜索端到端流程,适配RAG系统落地需求

二、Search语法深度解析

Milvus的Search接口是向量查询的核心,支持纯向量查询、标量过滤查询、批量查询等多种场景,先吃透语法和参数再动手实战更高效。

2.1 核心语法结构

python 复制代码
results = client.search(
    collection_name="集合名",  # 目标集合(必须)
    data=[[0.12, 0.23, ..., 0.88]],  # 查询向量列表(必须)
    anns_field="向量字段名",  # 要搜索的向量字段(必须)
    param={"metric_type": "L2", "params": {"nprobe": 10}},  # 搜索配置(必须)
    limit=10,  # 返回结果数量(默认10)
    filter="price > 50",  # 标量过滤条件(可选)
    output_fields=["product_id", "price"],  # 需要返回的标量字段(可选)
    offset=0  # 分页偏移量(可选)
)

2.2 关键参数详解

  • data:二维数组格式的查询向量列表,支持单向量和多向量批量查询。
  • anns_field:必须与集合创建时定义的向量字段名一致,不可随意填写。
  • param :搜索核心配置,包含距离度量类型和索引参数。
    • metric_type:距离计算方式,常用L2(欧氏距离)、IP(内积)、COSINE(余弦相似度)。
    • params:索引对应的参数,IVF类索引用nprobe(查询时遍历的聚类中心数),默认10。
  • limit:返回匹配结果的数量,建议根据实际需求设置5-100,过多会影响查询效率。
  • filter:标量过滤表达式,支持多条件组合(AND/OR),语法类似SQL。
  • output_fields:指定需要返回的标量字段,不指定时仅返回主键和距离。
  • offset:分页偏移量,配合limit实现分页查询,比如offset=2、limit=3表示查询第3-5条结果。

三、完整实战流程(MilvusClient方式)

本文采用MilvusClient新版接口(推荐生产使用),相比旧版更简洁、易维护,全程基于Python实现,可直接复制运行。

3.1 环境准备

首先确保已安装pymilvus库,若未安装执行以下命令:

bash 复制代码
pip install pymilvus>=2.4.0

3.2 步骤1:创建客户端与集合

集合是Milvus存储数据的基本单元,需先定义字段结构(标量+向量),再创建集合。

python 复制代码
from pymilvus import MilvusClient, FieldSchema, CollectionSchema, DataType
import random

# 1. 创建Milvus客户端(连接远程或本地Milvus服务)
client = MilvusClient(uri="http://192.168.229.128:19530")  # 替换为你的Milvus地址

# 2. 避免重复创建,删除已存在的同名集合
if client.has_collection("book"):
    client.drop_collection("book")

# 3. 定义字段结构(标量字段+向量字段)
fields = [
    # 主键字段:自增ID,无需手动插入
    FieldSchema(name="book_id", dtype=DataType.INT64, is_primary=True, auto_id=True),
    # 标量字段:图书标题(字符串类型)
    FieldSchema(name="title", dtype=DataType.VARCHAR, max_length=200),
    # 标量字段:图书分类(字符串类型)
    FieldSchema(name="category", dtype=DataType.VARCHAR, max_length=50),
    # 标量字段:图书价格(浮点型)
    FieldSchema(name="price", dtype=DataType.DOUBLE),
    # 向量字段:图书简介的嵌入向量(4维,实际场景需根据嵌入模型调整维度)
    FieldSchema(name="book_intro", dtype=DataType.FLOAT_VECTOR, dim=4)
]

# 4. 创建集合Schema
schema = CollectionSchema(
    fields=fields,
    description="用于图书搜索的混合类型集合(标量+向量)"
)

# 5. 最终创建集合
client.create_collection(collection_name="book", schema=schema)
print("集合创建成功!")

3.3 步骤2:批量插入测试数据

生成包含标量和向量的测试数据,批量插入集合,效率远高于单条插入。

python 复制代码
# 1. 定义测试数据的基础配置
num_books = 1000  # 数据总量
categories = ["科幻", "科技", "文学", "历史"]  # 图书分类选项
titles = ["量子世界", "AI简史", "时光之轮", "文明起源", "未来简史", "数据科学"]  # 图书标题前缀

# 2. 生成1000条测试数据(字典列表格式,与字段名对应)
data = []
for i in range(num_books):
    data.append({
        "title": f"{random.choice(titles)}_{i}",  # 标题+序号,避免重复
        "category": random.choice(categories),  # 随机分类
        "price": round(random.uniform(10, 100), 2),  # 10-100元随机价格,保留2位小数
        "book_intro": [random.random() for _ in range(4)]  # 4维随机向量(模拟嵌入结果)
    })

# 3. 批量插入数据到集合
insert_result = client.insert(
    collection_name="book",
    data=data
)

# 4. 验证插入结果
print(f"成功插入数据量:{len(insert_result['ids'])}")  # 输出插入的主键ID数量

3.4 步骤3:创建向量索引(提升查询效率)

向量索引是加速查询的关键,未创建索引时会执行全量扫描,效率极低。

python 复制代码
# 1. 准备索引参数(针对向量字段book_intro)
index_params = MilvusClient.prepare_index_params()

# 2. 配置索引信息(IVF_FLAT索引,适合中小规模数据)
index_params.add_index(
    field_name="book_intro",  # 必须是向量字段
    metric_type="L2",  # 距离计算方式:欧氏距离
    index_type="IVF_FLAT",  # 索引类型,新手推荐IVF_FLAT
    index_name="book_intro_index",  # 索引名称(自定义)
    params={"nlist": 128}  # 聚类中心数,建议值为数据量的平方根(1000的平方根≈32,这里取128适配更多数据)
)

# 3. 创建索引
client.create_index(
    collection_name="book",
    index_params=index_params
)

print("向量索引创建完成!")

3.5 步骤4:加载集合到内存(查询前必须执行)

Milvus的查询操作需要先将集合加载到内存,加载后可多次查询,无需重复加载。

python 复制代码
client.load_collection(collection_name="book")
print("集合已加载到内存,可执行查询操作!")

四、多场景查询案例实战

掌握基础流程后,通过4个核心场景实战,覆盖大部分实际使用需求。

4.1 场景1:基础向量查询(无过滤条件)

仅根据向量相似度查询,返回最匹配的结果。

python 复制代码
# 1. 生成查询向量(4维,与集合向量字段维度一致)
query_vector = [random.random() for _ in range(4)]

# 2. 执行基础向量查询
basic_results = client.search(
    collection_name="book",
    data=[query_vector],  # 单向量查询
    anns_field="book_intro",
    param={"metric_type": "L2", "params": {"nprobe": 10}},
    limit=5,  # 返回前5个最相似结果
    output_fields=["title", "category", "price"]  # 返回需要的标量字段
)

# 3. 解析并打印结果
print("\n=== 基础向量查询结果(前5条)===")
for idx, result in enumerate(basic_results[0]):
    print(f"第{idx+1}条:")
    print(f"  图书ID:{result['book_id']}")
    print(f"  相似度距离:{result['distance']:.4f}")  # 距离越小越相似
    print(f"  图书标题:{result['entity']['title']}")
    print(f"  分类:{result['entity']['category']}")
    print(f"  价格:{result['entity']['price']:.2f}元")
    print("-" * 40)

4.2 场景2:带过滤条件的混合查询(核心场景)

结合标量过滤+向量相似度,实现精准查询(如"科幻类+价格<50元"的相似图书)。

python 复制代码
# 1. 复用之前的查询向量(也可重新生成)
# 2. 执行混合查询:科幻类 + 价格<50元 + 向量相似
mixed_results = client.search(
    collection_name="book",
    data=[query_vector],
    anns_field="book_intro",
    param={"metric_type": "L2", "params": {"nprobe": 10}},
    filter="category == '科幻' and price < 50",  # 多条件过滤(AND连接)
    limit=3,  # 返回前3条匹配结果
    output_fields=["title", "category", "price"]
)

# 3. 解析结果
print("\n=== 混合查询结果(科幻类+价格<50元)===")
for idx, result in enumerate(mixed_results[0]):
    print(f"第{idx+1}条:")
    print(f"  图书ID:{result['book_id']}")
    print(f"  相似度距离:{result['distance']:.4f}")
    print(f"  图书标题:{result['entity']['title']}")
    print(f"  分类:{result['entity']['category']}")
    print(f"  价格:{result['entity']['price']:.2f}元")
    print("-" * 40)

4.3 场景3:分页查询(海量结果时使用)

当匹配结果过多时,通过offset+limit实现分页,避免一次性返回大量数据。

python 复制代码
# 执行分页查询:跳过前2条,返回接下来的3条
page_results = client.search(
    collection_name="book",
    data=[query_vector],
    anns_field="book_intro",
    param={"metric_type": "L2", "params": {"nprobe": 10}},
    filter="category == '科技'",  # 过滤科技类图书
    offset=2,  # 跳过前2条结果
    limit=3,  # 返回3条结果(第3-5条)
    output_fields=["title", "category", "price"]
)

# 解析结果
print("\n=== 分页查询结果(科技类,第3-5条)===")
for idx, result in enumerate(page_results[0]):
    print(f"第{idx+1}条(总第{idx+3}条):")
    print(f"  图书ID:{result['book_id']}")
    print(f"  相似度距离:{result['distance']:.4f}")
    print(f"  图书标题:{result['entity']['title']}")
    print(f"  价格:{result['entity']['price']:.2f}元")
    print("-" * 40)

4.4 场景4:批量查询(多向量同时查询)

支持一次性传入多个查询向量,每个向量独立返回匹配结果,效率更高。

python 复制代码
# 1. 生成2个查询向量
batch_query_vectors = [
    query_vector,  # 复用之前的向量
    [0.5, 0.5, 0.5, 0.5]  # 自定义向量
]

# 2. 执行批量查询:2个向量各返回2条结果
batch_results = client.search(
    collection_name="book",
    data=batch_query_vectors,  # 多向量批量查询
    anns_field="book_intro",
    param={"metric_type": "L2", "params": {"nprobe": 10}},
    limit=2,  # 每个向量返回2条结果
    output_fields=["title", "category"]
)

# 3. 解析结果(batch_results与查询向量一一对应)
print("\n=== 批量查询结果 ===")
for vec_idx, vec_results in enumerate(batch_results):
    print(f"\n查询向量{vec_idx+1}的匹配结果:")
    for res_idx, result in enumerate(vec_results):
        print(f"  第{res_idx+1}条:")
        print(f"    图书ID:{result['book_id']}")
        print(f"    相似度距离:{result['distance']:.4f}")
        print(f"    图书标题:{result['entity']['title']}")
        print(f"    分类:{result['entity']['category']}")

五、集合与索引状态验证

查询完成后,可通过以下方法验证集合和索引的状态,确保后续操作正常。

python 复制代码
# 1. 查看集合详情(字段、数据量等)
collection_info = client.describe_collection("book")
print("\n=== 集合详情 ===")
print(f"集合名称:{collection_info['collection_name']}")
print(f"字段数量:{len(collection_info['fields'])}")
print(f"数据量:{collection_info['num_entities']}")

# 2. 查看索引列表
index_list = client.list_indexes("book")
print("\n=== 索引列表 ===")
for index in index_list:
    print(f"索引名称:{index['index_name']}")
    print(f"关联字段:{index['field_name']}")
    print(f"索引类型:{index['index_type']}")

# 3. 卸载集合(释放内存,无需查询时执行)
client.release_collection(collection_name="book")
print("\n集合已卸载,内存已释放!")

六、Milvus新旧版本接口对比

很多开发者可能接触过旧版PyMilvus接口,这里整理核心差异,方便快速迁移。

功能 PyMilvus旧版(<2.3) MilvusClient新版(≥2.4)
连接管理 需要手动调用connections.connect() 客户端自动管理,创建时传入uri即可
数据插入格式 多列表结构(如ids=[], titles=[]) 字典列表格式(更直观,与字段名对应)
字段定义 需单独创建FieldSchema和CollectionSchema 可直接在create_collection中定义(简化)
返回结果格式 自定义对象,需通过属性访问(如res.id 标准化字典格式,键值对访问(更易用)
错误处理 需捕获特定异常类 统一错误码系统,排查更高效
动态字段支持 需要额外配置schema 开启参数即可支持,无需修改schema

推荐:新项目直接使用MilvusClient新版接口,旧项目逐步迁移,开发效率和维护性更优。

七、实战关键注意事项

  1. 向量维度必须一致:查询向量的维度需与集合向量字段的dim完全一致,否则会报错。
  2. 索引参数匹配:nprobe(查询聚类中心数)越大,查询精度越高但速度越慢,需根据数据量平衡(建议10-100)。
  3. 过滤条件语法:filter参数支持=、!=、>、<、>=、<=、IN等运算符,多条件用AND/OR连接,字符串需用单引号包裹。
  4. 集合加载:加载集合是重量级操作,避免频繁加载/卸载,建议长期查询时保持加载状态。
  5. 数据量适配:IVF_FLAT索引适合100万条以下数据,更大数据量可选择IVF_SQ8、HNSW等索引。

如果本文对你有帮助,欢迎点赞+关注,后续会持续输出AI大模型与向量数据库的实战内容~


相关推荐
ReinaXue1 小时前
跨模态预训练大模型【CLIP】:Contrastive Language–Image Pre-training
图像处理·人工智能·深度学习·计算机视觉·语言模型
福大大架构师每日一题1 小时前
PyTorch v2.9.1 发布:重要 Bug 修复与性能优化详解
人工智能·pytorch·bug
海阔的天空1 小时前
VSCode通过continue插件免费安装AI模型实现自动编程
运维·ide·人工智能·vscode·编辑器·ai编程
老段工作室1 小时前
微调自动语音识别模型(ASR),精准识别各种不标准发音 及蹩脚英文发音
人工智能·语音识别
吃肉夹馍不要夹馍1 小时前
【opencv图片倾斜矫正】
人工智能·opencv·计算机视觉
sca1p311 小时前
新南威尔士大学 LiM
论文阅读·人工智能·加密流量分类
weixin_457760001 小时前
EIOU (Efficient IoU): 高效边界框回归损失的解析
人工智能·数据挖掘·回归
美团技术团队1 小时前
AI Coding与单元测试的协同进化:从验证到驱动
人工智能
曹工不加班1 小时前
n8n 实战:工作流自动发布排版精美的公众号文章
人工智能·工作流引擎