如何用Python-Milvus向量数据库实现过滤搜索?
摘要:向量数据库中除了存储向量外也能像关系型数据库一样存储一些其他信息这些信息如何配合向量一起查询?这是本文要描述的重点 在大模型与向量检索快速普及的今天,Milvus 已经成为工业级向量数据库的主流选择。它专注于高效存储、管理和检索高维向量数据
向量数据库中除了存储向量外也能像关系型数据库一样存储一些其他信息这些信息如何配合向量一起查询?这是本文要描述的重点
在大模型与向量检索快速普及的今天,Milvus 已经成为工业级向量数据库的主流选择。它专注于高效存储、管理和检索高维向量数据,广泛用于推荐系统、图像检索、语义匹配等场景。
本文将带你完整走一遍 Milvus 最核心的使用流程,从环境连接、集合创建、数据写入、索引构建到向量混合检索,每一步都是生产环境可直接复用的标准实践。
一、连接 Milvus 服务
使用 MilvusClient 客户端,通过服务地址与认证信息建立连接,这是所有操作的入口。客户端封装了底层通信细节,让开发者可以用极简 API 完成向量数据库的全流程操作。
二、准备数据环境
为了保证实验环境干净,先对目标集合进行清理。随后开始定义集合结构,也就是 Schema。
Schema 是集合的 “骨架”,决定数据如何存储:
指定主键字段,支持自定义 ID;
定义向量字段,明确向量维度;
添加普通标量字段,如字符串、整型数据;
开启动态字段,灵活扩展未预先定义的属性。
结构定义完成后,即可创建集合,为后续数据写入做好准备。
三、插入结构化向量数据
准备一批包含向量与属性的测试数据,每条数据由唯一 ID、高维向量、字符串标签与数值属性组成。这些数据可以对应推荐系统中的物品特征、图片特征或文本向量。
通过插入接口批量写入数据,Milvus 会自动完成数据持久化,返回插入结果用于校验数据写入状态。
四、构建向量索引(性能关键)
向量数据本身无法直接高效检索,必须建立索引。索引是提升百万、千万级数据查询速度的核心手段。
实践中选择常用的 IVF_FLAT 索引类型,搭配余弦相似度计算方式:
索引类型平衡精度与性能,适合中小规模数据快速验证;
相似度度量决定向量之间的 “距离” 如何计算;
通过合理配置聚类参数,在查询速度与召回效果之间取得平衡。
索引创建支持异步执行,避免阻塞业务流程。创建完成后,可以查看索引信息,确认索引构建成功。
五、加载集合与向量混合检索
Milvus 集合默认处于离线状态,执行查询前必须加载到内存,这是保证检索正常运行的关键步骤。
最实用的能力是向量检索 + 标量过滤:
传入目标向量,系统自动计算相似度;
同时通过过滤条件做精准筛选,支持模糊匹配、数值范围判断;
指定返回字段,获取除向量外的业务属性;
限制返回条数,得到 Top-K 最相似结果。
最终返回的结果包含数据 ID、相似度距离与完整业务信息,可直接用于推荐、匹配、检索等业务逻辑。
六、总结
这套流程覆盖了 Milvus 最核心、最常用的功能:
连接与集合管理
Schema 结构设计
向量与标量数据写入
索引构建与参数配置
向量相似度检索 + 标量过滤
代码:
from pymilvus import MilvusClient, DataType, FieldSchema, CollectionSchema, Collection, connections
# 1. 初始化 Milvus 客户端连接
client = MilvusClient(
uri="http://192.168.211.128:19530",
token="root:Milvus"
)
# 2. 准备数据环境(清理历史数据)
# 删除名为 "data_t" 的集合(如果存在),避免重复创建导致报错
client.drop_collection(
collection_name="data_t"
)
# 3. 定义集合的 Schema(结构)
# create_schema: 创建集合结构对象
# auto_id=False: 不使用自动生成ID,由用户自定义id字段的值
# enable_dynamic_field=True: 启用动态字段,允许插入Schema中未定义的字段
schema = MilvusClient.create_schema(
auto_id=False,
enable_dynamic_field=True,
)
# 3.1 为Schema添加具体字段
# 主键字段:id,整型64位,is_primary=True标记为主键
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
# 向量字段:vector,浮点型向量,dim=5表示向量维度为5
schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=5)
# 字符串字段:color,VARCHAR类型,max_length=512限制最大长度
schema.add_field(field_name="color", datatype=DataType.VARCHAR, max_length=512)
# 整型字段:likes,记录点赞数,整型64位
schema.add_field(field_name="likes", datatype=DataType.INT64)
# 3.2 创建集合(Collection)
# collection_name: 集合名称
# schema: 上面定义的集合结构
client.create_collection(
collection_name="data_t",
schema=schema
)
# 4. 准备待插入的测试数据
# 每条数据包含:主键id、5维向量vector、颜色字符串color、点赞数likes
data = [
{"id": 0, "vector": [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592], "color": "pink_8682", "likes": 165},
{"id": 1, "vector": [0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104], "color": "red_7025", "likes": 25},
{"id": 2, "vector": [0.43742130801983836, -0.5597502546264526, 0.6457887650909682, 0.7894058910881185, 0.20785793220625592], "color": "orange_6781", "likes": 764},
{"id": 3, "vector": [0.3172005263489739, 0.9719044792798428, -0.36981146090600725, -0.4860894583077995, 0.95791889146345], "color": "pink_9298", "likes": 234},
{"id": 4, "vector": [0.4452349528804562, -0.8757026943054742, 0.8220779437047674, 0.46406290649483184, 0.30337481143159106], "color": "red_4794", "likes": 122},
{"id": 5, "vector": [0.985825131989184, -0.8144651566660419, 0.6299267002202009, 0.1206906911183383, -0.1446277761879955], "color": "yellow_4222", "likes": 12},
{"id": 6, "vector": [0.8371977790571115, -0.015764369584852833, -0.31062937026679327, -0.562666951622192, -0.8984947637863987], "color": "red_9392", "likes": 58},
{"id": 7, "vector": [-0.33445148015177995, -0.2567135004164067, 0.8987539745369246, 0.9402995886420709, 0.5378064918413052], "color": "grey_8510", "likes": 775},
{"id": 8, "vector": [0.39524717779832685, 0.4000257286739164, -0.5890507376891594, -0.8650502298996872, -0.6140360785406336], "color": "white_9381", "likes": 876},
{"id": 9, "vector": [0.5718280481994695, 0.24070317428066512, -0.3737913482606834, -0.06726932177492717, -0.6980531615588608], "color": "purple_4976", "likes": 765}
]
# 4.1 插入数据到集合
# collection_name: 目标集合名称
# data: 待插入的数据列表
res = client.insert(
collection_name="data_t",
data=data
)
# 打印插入结果(包含插入的行数、成功标志等)
print("数据插入结果:", res)
# 5. 为向量字段创建索引(提升向量检索效率)
# 5.1 准备索引参数对象
index_params = MilvusClient.prepare_index_params()
# 5.2 为vector字段添加索引配置
# field_name: 要创建索引的字段名(向量字段)
# metric_type: 相似度计算方式(COSINE:余弦相似度)
# index_type: 索引类型(IVF_FLAT:基于倒排文件的暴力检索,适合中小数据量)
# index_name: 索引名称(自定义)
# params: 索引参数(nlist:聚类数量,IVF_FLAT核心参数)
index_params.add_index(
field_name="vector",
metric_type="COSINE",
index_type="IVF_FLAT",
index_name="vector_index",
params={"nlist": 128}
)
# 5.3 执行索引创建
# sync=False: 异步创建索引(不等待创建完成就返回,适合大数据量)
client.create_index(
collection_name="data_t",
index_params=index_params,
sync=False # True表示同步等待索引创建完成,False为异步
)
# 5.4 查看集合中的索引列表
res = client.list_indexes(
collection_name="data_t"
)
# 打印索引列表(确认索引创建成功)
print("集合中的索引列表:", res)
# 6. 加载集合到内存(关键步骤)
# Milvus的集合默认是离线状态,检索前必须加载到内存,否则会报"集合找不到"错误
client.load_collection(collection_name="data_t")
# 7. 向量检索(核心功能)
# 7.1 定义待检索的目标向量(与数据中id=0的向量完全一致)
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
# 7.2 执行混合检索(向量相似度 + 标量过滤)
# collection_name: 目标集合
# data: 待检索的向量列表(支持批量检索,这里只传一个向量)
# limit: 返回相似度最高的前5条结果
# filter: 标量过滤条件(color以red开头 且 likes大于50)
# output_fields: 需要返回的字段(除了默认的id和距离,额外返回color、likes、vector)
res = client.search(
collection_name="data_t",
data=[query_vector],
limit=5,
filter='color like "red%" and likes > 50',
output_fields=["color", "likes", "vector"]
)
# 7.3 格式化打印检索结果
for hits in res: # hits对应每个检索向量的结果列表
print("\nTopK 检索结果:")
for hit in hits: # 遍历每条结果
# hit包含:id(主键)、distance(相似度距离)、entity(指定的输出字段)
print(hit)
运行结果:
数据插入结果: {'insert_count': 10, 'ids': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
集合中的索引列表: ['vector_index']
TopK 检索结果:
{'id': 4, 'distance': 0.5975796580314636, 'entity': {'vector': [0.4452349543571472, -0.8757026791572571, 0.8220779299736023, 0.46406289935112, 0.3033747971057892], 'color': 'red_4794', 'likes': 122}}
{'id': 6, 'distance': -0.24996188282966614, 'entity': {'vector': [0.8371977806091309, -0.015764368698000908, -0.31062936782836914, -0.5626669526100159, -0.8984947800636292], 'color': 'red_9392', 'likes': 58}}
更多学习资料尽在老虎网盘资源:老虎网盘资源
