Milvus 向量数据库

向量数据库系列文章目录

例如:第一章 向量数据库基础;第二章 Milvus 向量数据库


文章目录


前言

本文主要整理 Milvus 向量数据库相关内容,包括 Milvus 概念、性能、索引类型、部署方式、Docker 安装、密码配置、MilvusClient 操作、Collection/Schema/Index、数据插入、搜索、查询以及常见索引参数等。


Milvus向量数据库

一、Milvus

1.Milvus

  • Milvus是一个开源的向量数据库,专为高维向量数据的存储、查询和检索而设计。它支持多种类型的向量数据,如浮点数向量、整数向量等,并且提供了强大的向量相似度计算功能。
  • Milvus采用分布式架构,可以轻松地扩展到大规模数据集,同时保证了数据的一致性和可用性。
  • Milvus适用于处理和搜索大规模的高维向量数据,为AI应用和向量相似度搜索提供了加速引擎
  • 在大多数情况下,Milvus的性能是其他向量数据库的2-5倍,它能实现万亿级向量的毫秒级相似性搜索,而且Milvus还是开源的向量数据库。

2.关键概念和特点

  • 非结构化数据
    • 非结构化数据指的是数据结构不规则,没有统一的预定义数据模型,不方便用数据库二维逻辑表来表现的数据。包括图片、视频、音频、自然语言等多种非结构化数据。
    • Milvus可以处理非结构化数据,将其抽象为高维特征向量,从而实现高效的向量相似度搜索。
  • 特征向量
    • 特征向量是由embedding技术从离散变量(如图片、视频、音频、自然语言等各种非结构化数据)转变而来的连续向量。
    • 通过向量表示,Milvus可以捕捉到数据的语义相似性,使得不同模态的数据之间可以相互匹配。
  • 多模态搜索
    • Milvus自带多模态功能,支持机器学习方法处理和理解来自不同源的多种模态信息,如文本、图像、音频和视频等。
    • 这使得Milvus能够应用于多语言搜索、图像检索等多模态应用。
  • 大模型赋能
    • Milvus可以拓展大模型的边界,包括时间边界和空间边界。
    • 时间边界的拓展:Milvus使得大模型具有"长期记忆",能够处理新信息。
    • 空间边界的拓展:Milvus支持本地部署,解决大模型泄露隐私的问题。
  • Milvus 2.0
    • Milvus 2.0是一款云原生向量数据库,采用存储与计算分离的架构设计。

3.性能

  • 性能提升
    • 在新的Milvus 2.2 benchmark中,Milvus相比之前版本取得了50%以上的性能提升。
    • 在1M向量串行执行的场景下,Milvus实现了3ms以下的延迟,整体QPS超过了ElasticSearch的10倍。
  • 优化技巧
    • Milvus性能可通过合理预计数据量、表数目大小、QPS参数等指标进行优化。
    • 选择合适的索引类型和参数对于向量召回的性能至关重要,Milvus支持多种不同的索引,如Annoy、Faiss、HNSW、DiskANN等。
  • 高可用性和弹性
    • Milvus支持Kubernetes部署,以获得最佳可用性和弹性。
    • Milvus还支持数据分片、数据持久性、流式数据摄入、向量和标量之间的混合搜索、时间旅行等高级功能。
  • 云原生架构
    • Milvus是云原生的,采用存储与计算分离的架构设计,支持海量向量数据的实时召回。
    • Milvus基于FAISS、Annoy、HNSW等向量搜索库构建,解决稠密向量相似度检索的问题。

4.可扩展性

  • 高可扩展性
    • Milvus基于云原生分布式架构,能够实现百亿级别的向量索引扩展。
    • Milvus支持存储与计算分离,离线在线一体化,使得数据库在应对不同场景时更加灵活。
  • 生态支持
    • Milvus与多个大模型生态系统深度集成,包括OpenAI、Langchain、Semantic Kernel、Llama-Index、AutoGPT、Towhee、Hugging face、Cohere等,为用户提供了丰富的应用场景和解决方案。
  • 一键部署:
    • 用户可以通过控制台快速创建Milvus向量数据库实例,全流程平台托管,无需进行任何安装、部署和运维操作,有效减少搭建和运维成本开销。
  • 服务高可用
    • Milvus采用云原生分布式构建,具备故障自动切换和自愈能力,全面提升实例可用性。
    • Milvus还支持安全组管理,通过配置安全组,授权特定访问源,保证服务及数据的安全。
  • 完善监控:
    • Milvus向量数据库提供可视化监控面板,用户可以全面了解数据库实例的运行情况。

5.Milvus支持索引类型

  • FLAT:适用于需要100%召回率且数据规模相对较小(百万级)的向量相似性搜索应用。
  • IVF_FLAT:基于量化的索引,适用于追求查询准确性和查询速度之间理想平衡的场景(高速查询、要求高召回率)。
  • IVF_SQ8:基于量化的索引,适用于磁盘或内存、显存资源有限的场景(高速查询、磁盘和内存资源有限、接受召回率的小幅妥协)。
  • IVF_PQ:基于量化的索引,适用于追求高查询速度、低准确性的场景(超高速查询、磁盘和内存资源有限、接受召回率的实质性妥协)。
  • HNSW:基于图的索引,适用于追求高查询效率的场景(高速查询、要求尽可能高的召回率、内存资源大的情景)。
  • ANNOY:基于树的索引,适用于追求高召回率的场景(低维向量空间)。
  • Milvus还支持其他一些索引类型,如SCANN、DISKANN等。以及AUTOINDEX,这是一种自动选择最合适索引类型的功能。

6.Milvus运行快原因

  • 硬件感知优化:Milvus针对多种硬件架构和平台优化了性能,包括AVX512、SIMD、GPU和NVMe SSD。
  • 高级搜索算法:Milvus支持多种内存和磁盘索引/搜索算法,包括IVF、HNSW、DiskANN等,所有这些算法都经过了深度优化。与FAISS和HNSWLib等流行实现相比,Milvus的性能提高了30%-70%。
  • C++搜索引擎:向量数据库性能的80%以上取决于其搜索引擎。由于C++语言的高性能、底层优化和高效资源管理,Milvus将C++用于这一关键组件。最重要的是,Milvus集成了大量硬件感知代码优化,从汇编级向量到多线程并行化和调度,以充分利用硬件能力。
  • 面向列:Milvus是面向列的向量数据库系统。其主要优势来自数据访问模式。在执行查询时,面向列的数据库只读取查询中涉及的特定字段,而不是整行,这大大减少了访问的数据量。此外,对基于列的数据的操作可以很容易地进行向量化,从而可以一次性在整个列中应用操作,进一步提高性能。

7.Milvus支持各种类型的搜索功能

  • ANN 搜索:查找最接近查询向量的前K个向量。
  • 过滤搜索:在指定的过滤条件下执行ANN搜索。
  • 范围搜索:查找查询向量指定半径范围内的向量。
  • 混合搜索:基于多个向量场进行ANN搜索。
  • 全文搜索:基于BM25的全文搜索。
  • Rerankers:根据附加标准或辅助算法调整搜索结果顺序,完善初始ANN搜索结果。
  • 根据主键检索数据。
  • 查询使用特定表达式检索数据。

二、Milvus纯标量存储性能

1.Milvus集合里不能没有向量字段,而且向量指定最小2维。

2.Milvus与内存/Redis对比

存储 优点 缺点 适用场景
Milvus 1. 数据持久化 2. 减少组件依赖 3. 支持标量过滤查询 1. 标量检索速度可能略慢于内存 2. 需要设计合理的集合结构 需要简化架构、长期持久化的场景
内存/Redis 1. 键值查询极快 2. 适合高频读取 1. 需额外维护 Redis 2. 内存有限,可能丢失数据 对延迟敏感、能接受额外依赖的场景

3.性能

  • Milvus的标量过滤性能通常略慢于Redis(内存键值存储),但差距在毫秒级,对大多数应用可忽略。如果标量字段建立了索引,速度会进一步提升。
  • Redis的优势:纯内存操作,适合超高频读取(如每秒万次以上)。支持复杂数据结构(如 Hash、List)。

三、Milvus安装

1.Milvus三种部署方式

  • Milvus Lite
    • Milvus Lite是一个Python库,可导入到应用程序中。作为Milvus的轻量级版本,它非常适合在Jupyter笔记本或资源有限的智能设备上运行快速原型。
    • Milvus Lite支持与Milvus其他部署相同的API。
    • 与Milvus Lite交互的客户端代码也能与其他部署模式下的Milvus实例协同工作。
  • Milvus Standalone(当前选用此部署方式)
    • Milvus Standalone是单机服务器部署。
    • Milvus Standalone的所有组件都打包到一个Docker镜像中,方便部署。
  • Milvus Distributed
    • Milvus Distributed可部署在Kubernetes集群上。
    • 这种部署采用云原生架构,摄取负载和搜索查询分别由独立节点处理,允许关键组件冗余。它具有最高的可扩展性和可用性,并能灵活定制每个组件中分配的资源。
    • Milvus Distributed是在生产中运行大规模向量搜索系统的企业用户的首选。

2.Milvus硬件需求建议

  • 单机版本:4core CPU,16G内存,NVMe SSD。
  • 技巧版本:8core CPU,128G内存,NVMe SSD。

3.docker部署Milvus Standalone

  • 安装2.4.15版本的Milvus Standalone
  • 安装docker并安装docker-compose
  • 下载docker-compose.yaml文件
bash 复制代码
wget https://github.com/milvus-io/milvus/releases/download/v2.4.15/milvus-standalone-docker-compose.yml -O docker-compose.yml
  • 容器开机自启(可选)
    • 容器开机自启需要修改docker-compose.yaml文件内容。
    • 每个容器服务项中增加restart: always
    • 网络服务不用增加
  • 运行docker-compose.yaml文件(会自动下载镜像)
bash 复制代码
docker compose up -d

4.容器:milvus-standalone、milvus-etcd、milvus-minio启动

  • milvus-standalone容器使用默认设置为本地19530端口提供服务,并将其数据映射到当前文件夹中的volumes/milvus。
  • milvus-etcd容器不向主机暴露任何端口,并将其数据映射到当前文件夹中的volumes/etcd。
  • milvus-minio容器使用默认身份验证凭据在本地为端口9090和9091提供服务,并将其数据映射到当前文件夹中的volumes/minio。

5.增加/修改Milvus密码(可选)(失败)

  • 使用命令进入镜像环境:docker exec -it milvus-standalone /bin/bash
  • 修改/milvus/configs/milvus.yaml里的内容
    • 将authorizationEnabled: false修改为authorizationEnabled: true
    • 将defaultRootPassword: Milvus修改为defaultRootPassword: <密码>
  • 如果没有vim/vi/nano,可以使用sed命令修改
bash 复制代码
sed -i 's/authorizationEnabled: false/authorizationEnabled: true/' milvus.yaml
sed -i 's/defaultRootPassword: Milvus/defaultRootPassword: ************/' milvus.yaml
  • 重启单个容器:docker restart milvus-standalone

6.增加/修改Milvus密码(可选)(成功)

  • 使用命令进入镜像环境:docker exec -it milvus-standalone /bin/bash
  • 修改/milvus/configs/milvus.yaml里的内容
    • 将authorizationEnabled: false修改为authorizationEnabled: true
  • 如果没有vim/vi/nano,可以使用sed命令修改
bash 复制代码
sed -i 's/authorizationEnabled: false/authorizationEnabled: true/' milvus.yaml
  • 重启单个容器:docker restart milvus-standalone
  • 代码使用pymilvus库的connections和utility类,执行修改
    • 先连接,后修改。使用alias定义连接别名,使用using来调用指定的连接
    • 默认密码为Milvus,使用new_password参数设置新密码

代码

python 复制代码
from pymilvus import connections, utility
connections.connect(
    alias='default',
    host='192.168.1.101',
    port='19530',
    user='root',
    password='************',
)
utility.reset_password(
    user="root", 
    old_password="************", 
    new_password="************", 
    using="default"
) 

7.安装客户端

8.milvus支持两个端口:19530、9091

  • gRPC支持19530端口:连接不同Milvus sdk的Milvus服务器。
    • gRPC也是基于TCP协议的
  • RESTful API支持9091端口:使用HTTP客户端连接到Milvus服务器。

四、Milvus与FAISS

1.向量字段数量

  • FAISS是一个纯粹的单向量索引库,每个数据表(集合)只能存储一个向量
  • Milvus支持每个数据表存储多个向量。

2.非结构性数据

  • FAISS不支持结构化数据,也就是说不能有其他标量地数据。
  • Milvus支持结构化数据,也就是说能有多个标量地数据(标量数据如:一些属性数据,year,title等)。所以Milvus搜索时可以混合搜索(向量相似性 + 条件过滤)

3.对比

对比项 FAISS Milvus
多向量支持 ❌ 仅单向量 ✅ 支持多个向量字段
结构化过滤 ❌ 不支持 ✅ 支持(如 year > 2000)
分布式 ❌ 单机 ✅ 支持分布式
适用场景 小规模、简单相似性搜索 大规模、复杂多向量检索

五、Milvus多维向量与多向量字段

1.多向量

  • 多向量与多维度
    • 多维向量:一个向量里有很多维(如768维)
    • 多个向量字段:一条数据里有多个独立的向量(多个embedding)
  • Milvus 的多个向量字段
    • 每个向量字段:都是一个独立的向量,都有自己的维度,都有自己的索引,都可以单独检索
  • 场景:同一段文档有多种语义视角。
    • 语义视角:内容语义(正文),标题语义,关键词语义
    • 就是一段文档可有3个向量字段表示。而每个字段向量各有不同得维度表示。

代码

python 复制代码
schema = CollectionSchema(
    fields=[
        FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),

        # 向量字段 1:正文语义
        FieldSchema(name="content_vector", dtype=DataType.FLOAT_VECTOR, dim=768),

        # 向量字段 2:标题语义
        FieldSchema(name="title_vector", dtype=DataType.FLOAT_VECTOR, dim=384),

        # 向量字段 3:关键词语义
        FieldSchema(name="keyword_vector", dtype=DataType.FLOAT_VECTOR, dim=256),
    ]
)

2.Milvus表结构

  • 假设一个RAG文档库,每条记录代表一个chunk。
  • 每条记录得数据结构
python 复制代码
Collection: document_chunks
┌─────────┬───────┬───────┐
│ 字段名           │ 类型         │ 说明         │
├─────────┼───────┼───────┤
│ id               │ INT64 (PK)   │ 主键         │
│ doc_id           │ VARCHAR      │ 文档ID       │
│ chunk_index      │ INT32        │ 第几个chunk  │
│ content          │ VARCHAR      │ 原始文本     │
│ content_vector   │ FLOAT_VECTOR │ 正文语义向量 │
│ title_vector     │ FLOAT_VECTOR │ 标题语义向量 │
│ keyword_vector   │ FLOAT_VECTOR │ 关键词向量   │
└─────────┴───────┴───────┘
  • 有3个向量字段
python 复制代码
content_vector  ->  dim = 768   (768维向量)
title_vector    ->  dim = 384   (354维向量)
keyword_vector  ->  dim = 256   (256维向量)

3.Milvus创建表格(collection)

代码

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

fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
    FieldSchema(name="doc_id", dtype=DataType.VARCHAR, max_length=128),
    FieldSchema(name="chunk_index", dtype=DataType.INT32),
    FieldSchema(name="content", dtype=DataType.VARCHAR, max_length=65535),
    # 向量字段 
    FieldSchema(name="content_vector", dtype=DataType.FLOAT_VECTOR, dim=768),
    FieldSchema(name="title_vector", dtype=DataType.FLOAT_VECTOR, dim=384),
    FieldSchema(name="keyword_vector", dtype=DataType.FLOAT_VECTOR, dim=256),
]

schema = CollectionSchema(
    fields=fields,
    description="Document chunks with multiple vector fields"
)

六、Python简易使用Milvus

1.使用pymilvus库能够对接Milvus向量数据库的第三方库。

  • 安装pymilvus库:pip install pymilvus

2.连接到Milvus

  • 使用MilvusClient()方法,连接到Milvus
  • 参数:
    • uri:要链接的Milvus服务的地址包括IP和port。
    • db_name:Milvus服务的数据库名称。默认"default"
    • user:Milvus服务账号名(可选)
    • password:Milvus服务密码(可选)
    • token:Milvus服务token(可选)
  • 返回链接对象
  • 返回链接对象后,使用close()断开连接

代码

python 复制代码
from pymilvus import MilvusClient

client = MilvusClient(
    db_name="default",
    uri="http://192.168.1.101:19530",
    # user="root",
    # password="************",
)

3.connections.connect()与MilvusClient

  • connections.connect()和MilvusClient都是连接Milvus的方式
  • connections.connect()(旧版/Golang SDK风格):
    • 来自pymilvus主要模块,属于较低层级的连接方式。
    • 主要用于建立与管理Milvus的连接(通过alias别名支持多连接),但不直接提供数据操作的 API。
    • 连接后需通过utility等具体类操作数据,API更面向Milvus的核心概念(如集合、分区、索引等)。
  • MilvusClient(新版/Python SDK风格):
    • 是PyMilvus 2.x引入的高级封装,提供更简单的、面向RESTful/gRPC接口的客户端。
    • 直接集成常见操作(如插入、搜索、删除),API更简洁。

4.数据库操作

  • 返回链接对象后,使用list_databases()方法,列出所有数据库。
  • 返回链接对象后,使用create_database(db_name)方法,创建数据库。
    • 如果数据库存在,创建会报错。
  • 返回链接对象后,使用using_database(db_name)方法,进入/使用数据库。
  • 返回链接对象后,使用drop_database(db_name)方法,删除数据库。

5.集合加载/释放

  • 集合有一个加载或释放的状态。加载是指将集合的数据(包括向量和索引)从磁盘加载到内存(或GPU显存),以便进行高效的向量检索。
  • 释放状态下的集合无法操作数据。新创建的集合会默认加载状态。
  • Milvus不会对任何集合作自动加载的动作。
  • 集合需要修改/新增索引时,需要在集合释放的状态下操作。
  • 加载/释放状态
状态 是否可查询 内存占用 典型场景
加载 可检索 占用内存/显存 高频访问的集合
释放 不可检索 仅占磁盘 冷数据或归档数据
  • 返回链接对象后,使用load_collection()方法加载集合,collection_name参数为集合名称字符串。
  • 返回链接对象后,使用release_collection()方法释放集合,collection_name参数为集合名称字符串。

6.创建集合

  • 使用IndexParams()方法创建索引对象。并使用索引对象的add_index()方法定义索引的内容。add_index()参数:
    • field_name:指定添加索引的字段名。如"vector"
    • index_type:索引类型,如"FLAT","IVF_FLAT","HNSW","ANNOY"等
    • index_name:索引名称字符串,默认与字段名相同。
    • metric_type:距离度量类型,如"L2"(欧氏距离),"IP"(内积),"COSINE" (余弦相似度)
    • params:特定索引类型的额外参数。取决于使用的索引类型。如:
      • 对于IVF_FLAT或IVF_SQ8索引,需要"nlist"参数,表示聚类中心数量。
      • 对于HNSW索引,需要"efConstruction"参数,表示索引构建时的搜索范围。和"M"参数,表示每个节点的最大连接数
  • 返回链接对象后,使用create_collection()方法,创建集合(数据库的表)
  • 参数:
    • collection_name:集合名称字符串,必须唯一。如:"my_collection"
    • schema:集合的架构定义,可使用 MilvusClient.create_schema()创建的schema对象。如果提供此参数,dimension参数将被忽略
    • dimension:单个向量字段的维度整数,用于生成向量嵌入的模型决定。如128,384,1536等。说明这个是单个字段的向量表。注意:如果提供了schema参数,并且schema中已经为向量字段设置了维度,则此参数将被忽略
    • index_params:定义好内容的索引对象。如果不指定,默认AUTOINDEX
    • drop_old:当集合已存在时是否先删除旧集合再创建新集合,默认False
    • auto_id:是否自动生成主键ID,默认True,插入数据时不需要提供主键值
    • enable_dynamic_field:是否启用动态字段,默认True,可在插入数据时添加架构中未定义的字段
    • timeout:操作超时时间数(秒)。如果超时会抛出异常。默认None(不超时)
    • consistency_level:一致性级别,可选:"Strong","Session","Bounded","Eventually"
    • ttl:集合的生存时间(秒),超过此时间后数据将被自动删除。默认为0,表示永不过期

代码

python 复制代码
from pymilvus import MilvusClient
from pymilvus.milvus_client import IndexParams

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")

# 定义索引
index_params = IndexParams()
index_params.add_index(
    field_name="title_vector",
    index_type="FLAT",
    metric_type="L2",
    params={},
)

client.create_collection(
    collection_name="my_collection",
    dimension=128,
    index_params=index_params,
)

7.指定字段创建集合

  • 使用FieldSchema()方法,创建某一个字段对象,参数:
    • name参数名
    • dtype字段类型
    • is_primary是否主键
    • auto_id:是否自动生成主键ID
    • dim:向量维度数值
    • max_length:数据最长长度。
  • CollectionSchema()方法,创建collection的纲要对象,参数:
    • fields:字段对象列表
    • description:描述字符串
    • enable_dynamic_field:是否启用动态字段,默认True
  • 返回链接对象后,再使用create_collection()方法,创建集合。参数如上。

代码

python 复制代码
from pymilvus import MilvusClient, DataType, FieldSchema, CollectionSchema
from pymilvus.milvus_client import IndexParams

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")

# 定义索引
index_params = IndexParams()
index_params.add_index(
    field_name="vector",
    index_type="FLAT",
    metric_type="L2",
    params={},
)

# 定义字段
fields = [
    # 主键字段
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True), 
    # 向量字段,维度为128
    FieldSchema(name="vector", dtype=DataType.FLOAT_VECTOR, dim=128),
    # 文本字段
    FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=512), 
    FieldSchema(name="producer", dtype=DataType.VARCHAR, max_length=256),
    FieldSchema(name="creator", dtype=DataType.VARCHAR, max_length=256),
    FieldSchema(name="creationdate", dtype=DataType.VARCHAR, max_length=256),
    FieldSchema(name="title", dtype=DataType.VARCHAR, max_length=512),
    FieldSchema(name="author", dtype=DataType.VARCHAR, max_length=256),
    FieldSchema(name="moddate", dtype=DataType.VARCHAR, max_length=256),
    FieldSchema(name="source", dtype=DataType.VARCHAR, max_length=256),
    FieldSchema(name="total_pages", dtype=DataType.INT64),
    FieldSchema(name="page", dtype=DataType.INT64),
    FieldSchema(name="page_label", dtype=DataType.VARCHAR, max_length=256),
]

# 定义集合的schema
schema = CollectionSchema(
    fields=fields,
    description="这是一个带有自定义字段的示例集合",
    enable_dynamic_field=True
)

# 创建集合
client.create_collection(
    collection_name="my_collection",
    schema=schema,
    index_params=index_params,
)

# 查看集合结构
collection_info = client.describe_collection("my_collection")
print(collection_info)

结果

text 复制代码
{
    "collection_name": "my_collection",
    "auto_id": True,
    "num_shards": 1,
    "description": "这是一个带有自定义字段的示例集合",
    "fields": [
        {
            "field_id": 100,
            "name": "id",
            "description": "",
            "type": <DataType.INT64: 5>,
            "params": {},
            "auto_id": True,
            "is_primary": True,
        },
        {
            "field_id": 101,
            "name": "vector",
            "description": "",
            "type": <DataType.FLOAT_VECTOR: 101>,
            "params": {"dim": 128},
        },
...
        {
            "field_id": 112,
            "name": "page_label",
            "description": "",
            "type": <DataType.VARCHAR: 21>,
            "params": {"max_length": 256},
        },
    ],
    "functions": [],
    "aliases": [],
    "collection_id": 458490636546779991,
    "consistency_level": 2,
    "properties": {},
    "num_partitions": 1,
    "enable_dynamic_field": True,
    "created_timestamp": 458494955174494213,
}

8.Milvus数据类型

常量 相当于常数 字段类型 描述
BOOL 1 标量 布尔类型
INT8 2 标量 8位整型
INT16 3 标量 16位整型
INT32 4 标量 32位整型
INT64 5 主键,标量 64位整型
FLOAT 10 标量 单精度浮点型
DOUBLE 11 标量 双精度浮点型
VARCHAR 21 主键,标量 字符串类型,max_length=65,535
BINARY_VECTOR 100 向量 二进制向量类型
FLOAT_VECTOR 101 向量 32位单精度浮点数向量
FLOAT16_VECTOR 102 向量 16位半精度浮点数向量
BFLOAT16_VECTOR 103 向量 16位半精度浮点数向量,比FLOAT16_VECTOR显存占用量更小,精度更低。
SPARSE_FLOAT_VECTOR 104 向量 稀疏向量,存储非零元素及其相应索引列表
ARRAY 22 复合 数组,就是python中的列表
JSON 23 复合 json文档,就是python中的字典
NONE 0 空类型,无法设置为字段类型,milvus返回的格式,
UNKNOWN 999 未知类型,无法设置为字段类型,milvus返回的格式。

9.集合操作

  • 返回链接对象后,使用list_collections()方法,列出所有集合
  • 返回链接对象后,使用has_collection()方法,判断集合是否存在,参数collection_name为集合名称字符串
  • 返回链接对象后,使用drop_collection()方法,删除集合,参数collection_name为集合名称字符串

代码

python 复制代码
from pymilvus import MilvusClient

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")

print(client.list_collections())
client.has_collection("example")
client.drop_collection("example")

结果

text 复制代码
['example', 'my_collection', 'my_custom_collection', 'my_custom']
True

10.集合信息

  • 返回链接对象后,使用describe_collection()方法获取集合信息,参数collection_name为集合名称字符串
  • 返回集合属性字典

代码

python 复制代码
from pymilvus import MilvusClient

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
collection_info = client.describe_collection(collection_name="my_collection")
print(collection_info)

结果

text 复制代码
{
    "collection_name": "my_collection",
    "auto_id": False,
    "num_shards": 1,
    "description": "",
    "fields": [
        {
            "field_id": 100,
            "name": "id",
            "description": "",
            "type": <DataType.INT64: 5>,
            "params": {},
            "is_primary": True,
        },
        {
            "field_id": 101,
            "name": "vector",
            "description": "",
            "type": <DataType.FLOAT_VECTOR: 101>,
            "params": {"dim": 128},
        },
    ],
    "functions": [],
    "aliases": [],
    "collection_id": 458490636546761400,
    "consistency_level": 2,
    "properties": {},
    "num_partitions": 1,
    "enable_dynamic_field": True,
    "created_timestamp": 458494049925988359,
}

11.查看索引

  • 返回链接对象后,使用list_indexes()方法,查看集合内所有索引名称的列表,参数collection_name为集合名称字符串
  • 返回链接对象后,使用describe_index()方法,查看指定索引详情,参数collection_name为集合名称字符串,参数index_name为索引名称字符串。

代码

python 复制代码
from pymilvus import MilvusClient

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")

index_names = client.list_indexes(collection_name="my_collection")
print(index_names)

index_info = client.describe_index(
    collection_name="my_collection",
    index_name='vector'          # 从上面获取的索引名称列表中选择
)
print(index_info)                # 输出索引详细信息

结果

text 复制代码
['vector']
{'index_type': 'AUTOINDEX', 'metric_type': 'COSINE', 'field_name': 'vector', 'index_name': 'vector', 'total_rows': 0, 'indexed_rows': 0, 'pending_index_rows': 0, 'state': 'Finished'}

12.删除索引

  • 删除索引前,需要先释放集合,再删除。
  • 返回链接对象后,使用release_collection()方法释放集合,参数collection_name为集合名称字符串。
  • 返回链接对象后,使用drop_index()方法删除索引,参数collection_name为集合名称字符串。参数index_name为索引名称字符串,如"vector"
    • 删除索引成功或失败,都是没有提示信息的。

代码

python 复制代码
from pymilvus import MilvusClient
from pymilvus.milvus_client import IndexParams

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")

client.release_collection(collection_name="my_collection")
client.drop_index(collection_name="my_collection", index_name="vector")

13.增加索引

  • Milvus规定每个字段最多只能有一个索引。需要先删除再增加再加载。
  • 使用IndexParams()和add_index()方法,创建有内容的索引对象。
  • 返回链接对象后,使用create_index()方法修改索引,参数collection_name为集合名称字符串,参数index_params为index_params对象
  • 返回链接对象后,使用load_collection()方法加载集合,参数collection_name为集合名称字符串。

代码

python 复制代码
from pymilvus import MilvusClient
from pymilvus.milvus_client import IndexParams

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")

index_params = IndexParams()
index_params.add_index(
    field_name="vector",
    index_type="FLAT",
    metric_type="L2",
    params={},
)

client.create_index(collection_name="my_collection", index_params=index_params)
client.load_collection(collection_name="my_collection")

14.Milvus异步操作

  • 在Milvus中,为了高性能运作,所以添加或更新数据的操作都是异步非阻塞的,对于刚添加或更新入库的数据,有可能无法立即查询出来。

15.get获取数据

  • 返回链接对象后,使用get()方法,获取指定id的数据
  • 参数:
    • collection_name:集合名称字符串
    • ids:为需要获取的id数值或者id数值列表

代码

python 复制代码
from pymilvus import MilvusClient
from pymilvus.milvus_client import IndexParams

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")

client.get(
    collection_name="my_collection",
    ids=[458476772159659732, 458476772159659737]
)

16.insert写入数据

  • 返回链接对象后,使用insert()方法,写入数据
  • 参数:
    • collection_name:集合名称字符串
    • data:插入数据对象。也可以是一个数据对象的列表,同时插入多条数据。

代码

python 复制代码
from pymilvus import MilvusClient

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")

# 创建一个384维的向量(用0填充示例)
search_vector = [0.0] * 384
# 可以设置一些值
search_vector[0] = 0.05
search_vector[1] = 0.23
search_vector[2] = 0.07
search_vector[3] = 0.45
search_vector[4] = 0.13

res1 = client.insert(
    collection_name="my_collection",
    data={
        "vector": search_vector,
        "text": "测试22", 
        "producer": "测试1",
        "creator": "测试1",
        "creationdate": "测试1",
        "title": "测试1",
        "author": "测试1",
        "moddate": "2022-03-31T00:21:48+08:00",
        "source": "测试1",
        "total_pages": 1,
        "page": 1,
        "page_label": "测试1",
    },
)
# data可以是:data={[...],[...]}插入多个数据
print(res1)

结果

text 复制代码
{'insert_count': 1, 'ids': [458490636546304315]}

17.search向量/标量混合查询数据

  • 返回链接对象后,使用search()方法,根据向量相似度,查询数据
  • 参数:
    • collection_name:(字符串,必需)执行搜索的集合的名称。
    • data:(列表,必需)包含一个或多个查询向量的列表。每个查询向量的维度必须与集合中向量字段的维度一致。
    • limit:(整数,可选)指定要返回的最相似结果的数量。默认值为10。
    • filter:(字符串,可选)用于对标量字段进行过滤的表达式。它允许在搜索结果中添加额外的条件。例如:
      • 'total_pages > 10'
      • 'text == "my_collection"'
      • 'producer in "A", "B"'
      • 'creationdate >= "2023-01-01"'
      • 支持and, or, not等逻辑运算符。也支持使用like
    • output_fields:(列表,可选)指定返回标量字段名称的字符串列表。如果不指定,默认不返回任何标量字段。
    • search_params:(字典,必需)包含搜索算法特定参数的字典。至少需要包含metric_type。
      • "metric_type":(字符串,必需)距离公式类型,必须与集合创建时或索引创建时指定的度量类型一致。常见有"L2","IP","COSINE"。
      • "params":(字典,可选)索引搜索参数。取决于使用的索引类型。如:
python 复制代码
对于IVF_FLAT或IVF_SQ8索引,需要"nprobe"参数,表示在搜索时要探测的聚类数量。
对于HNSW索引,需要"ef"参数,表示搜索的邻居数量。
  • consistency_level:(字符串,可选)指定搜索的一致性级别。可选值包括"Strong" , "Bounded" , "Eventually" , "Session"。
  • expr:(字符串,可选)用于对结构化数据过滤,也就是只能针对标量数据。类似于SQL中的WHERE子句。它允许在向量相似性搜索的基础上,进一步筛选符合特定条件的记录。(2.x版本以后弃用了,改用filter,功能一样)
    • expr能够使用比较运算符如=,逻辑运算符如or,字符串操作如like。
    • 被搜索的字符串有特殊字符需要双引号("sci-fi"),其他直接写。
    • 字符需要区分大小写。
  • timeout:(浮点数,可选)搜索操作的超时时间(秒)。如果搜索超时会抛出异常。默认值为None (不超时)。
  • partition_names:(列表,可选)指定搜索的分区的字符串列表。如果未指定,则在所有分区中搜索。
  • anns_field:(字符串,可选)如果集合中有多个向量字段,可以指定要执行相似度搜索的向量字段的名称。默认使用集合的第一个向量字段。

代码

python 复制代码
from pymilvus import MilvusClient

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")

# 创建一个384维的向量(用0填充示例)
search_vector = [0.0] * 384
# 可以设置一些值
search_vector[0] = 0.05
search_vector[1] = 0.23
search_vector[2] = 0.07
search_vector[3] = 0.45
search_vector[4] = 0.13

expr = '''
    (genre == "sci-fi" OR genre == "action") 
    AND moddate >= 2010 
    AND rating > 7.5 
    AND title LIKE "%Star%"
'''

res = client.search(
    collection_name="my_collection",
    data=[search_vector],
    limit=3,
    # filter='name == "测试5" and id > 2',
    filter='text == "测试1"',
    expr=expr
    search_params={"metric_type": "L2", "params": {}},
    # output_fields=["pk", "text", "moddate"],
)
for row in res[0]:
    print(row)

结果

text 复制代码
{'id': 458490636546304309, 'distance': 0.0, 'entity': {}}
{'id': 458490636546304311, 'distance': 0.0, 'entity': {}}

# 如果增加了output_fields=["pk", "text", "moddate"]
{'id': 458490636546304309, 'distance': 0.0, 'entity': {'pk': 458490636546304309, 'text': '测试1', 'moddate': '2022-03-31T00:21:48+08:00'}}
{'id': 458490636546304311, 'distance': 0.0, 'entity': {'pk': 458490636546304311, 'text': '测试1', 'moddate': '2022-03-31T00:21:48+08:00'}}

18.query纯标量查询数据

  • 返回链接对象后,使用query()方法,查询普通数据
  • 参数和search()相似,但没有data参数和anna_field参数。

代码

python 复制代码
from pymilvus import MilvusClient

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")

res = client.query(
    collection_name="my_collection",
    filter='text == "测试1"',
    output_fields=["pk", "text", "moddate"],
)

for row in res[0]:
    print(row)

结果

text 复制代码
{'pk': 458490636546304309, 'text': '测试1', 'moddate': '2022-03-31T00:21:48+08:00'}
{'pk': 458490636546304311, 'text': '测试1', 'moddate': '2022-03-31T00:21:48+08:00'}

19.upsert修改数据

  • 返回链接对象后,使用upsert()方法,根据id修改对应内容数据
  • 参数
    • collection_name(字符串,必需):执行搜索的集合的名称。
    • data(列表,必需):包含一个或多个查询向量的列表。为需要修改的数据。

代码

python 复制代码
from pymilvus import MilvusClient

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
res = client.query(
    collection_name="my_collection",
    filter='text == "测试1"',
    output_fields=["*"]                  # 返回所有字段
)

row = res[0]
row["moddate"] = "2025-01-01T00:00:00+08:00"  # 需要修改的某个字段,其他不变
client.upsert(
    collection_name="my_collection", 
    data=[row]
)

20.delete 删除数据

  • 返回链接对象后,使用delete()方法,根据id删除对应内容数据
  • 参数
    • collection_name(字符串,必需):执行搜索的集合的名称。
    • ids(列表,必需):为需要删除数据的id列表。
    • filter(字符串,可选):为指定删除数据的数据。ids和filter二选一。

代码

python 复制代码
from pymilvus import MilvusClient

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")

client.delete(
    collection_name="my_collection",
    ids=[458490636546304309, 458490636546304311]
)
client.delete(
    collection_name="my_collection",
    filter='text == "xxx"'
)

21.flush数据持久化

  • 链接对象操作完后,使用flush()方法,将数据持久化。(非必要操作)
  • 作用
    • 将内存中的数据持久化到磁盘:强制将指定集合中所有仍在内存缓冲区中的插入、删除或更新操作刷新到磁盘存储。
    • 确保数据可见性:在flush操作完成后,新插入的数据将立即可被搜索到。
    • 创建新段(segment):Milvus会自动将数据组织成段,flush操作会触发新段的创建。
  • 参数
    • collection_name(字符串,必需):执行搜索的集合的名称。

代码

python 复制代码
from pymilvus import MilvusClient

client = MilvusClient(db_name="default",uri="http://192.168.1.101:19530")
client.insert(
    collection_name="my_collection",
    data={
        "vector": search_vector,
        "text": "测试22", 
        "producer": "测试1",
    },
)
client.flush(collection_name="my_collection")

七、Milvus索引性能调优

1.Milvus索引性能调优关键因素:

  • 数据规模:向量数量(数据量)越大,索引优化的影响越显著。
  • 速度与精度:有些索引(如 FLAT)精度高但查询慢,而ANN(如IVF、HNSW)可加速查询但会牺牲部分精度。
  • 内存与存储限制:索引(如HNSW)占用大量内存,而IVF_PQ可降低存储需求。
  • 数据分布:如果数据聚类性强,选择合适的索引参数可以提升检索效率。

2.索引类型调优技巧

  • FLAT(暴力搜索)
    • 适用场景:小规模数据(<100K),需要最高精度的场景,如金融风控、医学影像分析等。
    • 特点:进行穷举搜索,不对数据进行压缩,保证100%的召回率和精确性
    • 调优技巧:
      • 使用GPU加速计算:FLAT搜索是计算密集型任务,启用GPU可以显著提高查询速度。
      • 优化并行搜索:可以在客户端或服务端并行处理多个查询,提高吞吐量。
      • 如果数据量增长,可以考虑转换为IVF或HNSW以提升搜索效率。

代码

python 复制代码
index_params.add_index(
    field_name="vector",
    index_type="FLAT",
    metric_type="L2",
    params={},
)
  • IVF_FLAT(倒排文件索引)
    • 适用场景:中等规模数据(>100K),需要平衡查询速度和存储占用,如推荐系统、搜索引擎等。
    • 调优技巧:调整 nlist(索引构建时的聚类中心数量):
      • nlist越大,索引划分的簇越多,索引构建时间变长,但查询效率提高。
      • 经验法则:nlist约为数据集数量的,如1M数据可设nlist=1024。
    • 调优技巧:调整 nprobe(搜索时的簇数):
      • nprobe越大,搜索范围越广,精度提升但查询速度下降。
      • 经验法则:nprobe设为nlist的1%-10%。

代码

python 复制代码
index_params.add_index(
    field_name="vector",
    index_type="IVF_FLAT",
    metric_type="L2",
    params={
        "nlist": 1024
    }
)
  • IVF_SQ8 索引
    • 适用场景:相对于IVF_FLAT可加速查询,同时降低存储需求。
    • 特点:结合IVF和标量量化(SQ),将每个浮点数(4字节)压缩为1字节,减少内存占用。
    • 调优与IVF_FLAT相似
  • IVF_PQ 索引
    • 适用场景:相对于IVF_FLAT可减少存储占用,但可能牺牲部分精度。
    • 特点:结合IVF和乘积量化(PQ),进一步压缩数据存储需求。
    • 调优与IVF_FLAT相似

代码

python 复制代码
index_params.add_index(
    field_name="vector",
    index_type="IVF_PQ",
    metric_type="L2",
    params={
        "nlist": 128
        "m": 4,                    # 量化因子数
        "nbits": 8
    }
)
  • HNSW(分层导航小世界图)
    • 适用场景:高并发、低延迟查询,如AI聊天机器人、实时推荐系统等。
    • 调优技巧:调整M(每个节点的最大连接数):
      • M越大,索引构建时间增加,但查询精度更高。
      • 经验法则:一般设置 M = 16~32。
    • 调优技巧:调整efConstruction(索引构建时的搜索范围):
      • efConstruction越大,索引质量越好,但构建时间增加。
      • 推荐范围:efConstruction = 100~200。
    • 调优技巧:调整ef(搜索时的搜索范围):
      • ef越大,搜索精度越高,但查询速度变慢。
      • 经验法则:ef设置为50~200,适当调整以平衡精度和速度。

代码

python 复制代码
index_params.add_index(
    field_name="vector",
    index_type="HNSW",
    metric_type="L2",
    params={
        "M": 16,
        "efConstruction": 200
    }
)
  • SCANN(可扩展最近邻搜索)
    • 适用场景:超大规模数据(>10M),存储受限但需要高效搜索,如Google搜索、广告投放等。
    • 调优技巧:
      • 调整nlist和nprobe,与IVF_FLAT相似,优化搜索范围。
      • 使用PCA预处理数据,减少维度,提高搜索速度。
      • 结合PQ进行量化,进一步降低存储成本。

代码

python 复制代码
index_params.add_index(
    field_name="vector",
    index_type="SCANN",
    metric_type="L2",
    params={
        "nlist": 1024
        "reorder_k": 64
    }
)

3.其他优化技巧

  • 增加查询并发数
    • 使用批量查询代替单次查询,减少调用开销。
    • 配置Milvus服务器的worker数量,提升处理能力。

代码

python 复制代码
res = client.search(
    collection_name="my_collection",
    data=[search_vector],
    limit=3,
    # filter='name == "测试5" and id > 2',
    filter='text == "测试1"',
    search_params={"metric_type": "L2", "params": {"nprobe": 32}},
    batch_size=100,
)
  • 预加载索引,减少I/O开销
    • 在大规模数据下,避免频繁加载索引,可以使用Milvus partition功能,将数据拆分成多个分区,仅在需要时加载相关分区。
  • 选择合适的距离度量方式
    • L2(欧氏距离):适用于标准化数据,如图像、语音特征。
    • IP(内积):适用于推荐系统,计算向量相似度。
    • COSINE(余弦相似度):适用于文本、自然语言处理任务。

4.选型指南

索引类型 适用场景 精确度 查询速度 内存需求
FLAT 小数据集,需 100% 召回 100%
IVF_FLAT 大数据集,需较高召回 90%+(受nprobe影响)
IVF_SQ8 内存有限,可接受轻微精度损失 比IVF_FLAT轻微差距
IVF_PQ 内存有限,可接受较大精度损失 比IVF_FLAT较大差距 极快 极低
SCANN 高精度,内存充足 90%+ 极快
HNSW 高精度,内存充足 95%+(受ef影响) 极极快

5.结论

  • 小规模数据(<100K),选择FLAT以获得最高精度。
  • 中等规模数据(>100K),使用IVF调优nlist和nprobe以提高查询效率。
  • 超大规模数据(>10M),选择SCANN并结合量化优化存储。
  • 高并发、低延迟应用,使用HNSW优化M和ef参数。

八、LangChain使用Milvus作向量数据库

1.langchain-milvus库:能够在langchain中使用Milvus向量数据库。

2.需要安装Milvus的LangChain的插件:pip install langchain-milvus

3.创建向量数据库对象

  • 使用Milvus()方法,创建一个向量数据库对象
  • 参数:
    • embedding_function:嵌入模型对象
    • connection_args:连接Milvus服务器的配置参数字典,有:
      • uri: Milvus服务器地址字符串 (如 "http://localhost:19530")
      • token: 认证令牌 (如果启用认证)
      • secure: 布尔值,是否使用安全连接
      • user:用户名(如果需要)
      • password:密码(如果需要)
      • db_name:选用(或创建)数据库名(如果需要)
    • collection_name:要创建或连接的集合名字符串
    • drop_old:当集合已存在时是否先删除旧集合再创建新集合,默认False
    • auto_id:是否自动生成主键ID,默认True
    • consistency_level:设置集合的一致性级别字符串,可选值:"Strong", "Session"(默认), "Bounded", "Eventually", "Customized"
    • index_params:创建集合时,配置向量索引的参数字典,有:
      • index_type: 索引类型 (如 "FLAT", "IVF_FLAT", "HNSW" 等)
      • metric_type: 相似度度量方式 ("L2", "IP", "COSINE")
      • params: 特定索引类型的参数
    • search_params:搜索集合时的参数配置字典
      • metric_type: 相似度度量方式 ("L2", "IP", "COSINE")
      • params: 特定索引类型的参数
  • 定义字段名称参数:一般情况下会默认定义了3个必有的字段,和其他字段
    • primary_field:定义主键字段名,默认"pk"
    • text_field:定义存储原始文本的字段名,默认"text"
    • vector_field:存储向量的字段名,默认"vector"
    • fields:定义其他字段列表(如元数据字段)默认None
  • 返回向量数据库对象

4.向量数据库对象增加数据

  • 返回向量数据库对象后,使用add_documents()方法,增加document列表。
  • 参数document为document列表

5.创建检索器对象

  • 返回向量数据库对象后,使用as_retriever()方法,返回向量数据库检索器对象retriever。

6.自动新建标量字段

  • 在document对象中,可能会存在metadata的字典数据。Milvus会自动地为metadata里地每个元素创建一个字段,并保存。
  • 搜索时,可以使用标量字段作结构化过滤,如year > 2010

7.示例

代码

python 复制代码
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_openai import ChatOpenAI
from langchain_milvus import Milvus
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_community.document_loaders import UnstructuredMarkdownLoader
from operator import itemgetter
from langchain_text_splitters import MarkdownTextSplitter

# 初始化 LLM和嵌入模型
llm = ChatOpenAI(
    model="Pro/deepseek-ai/DeepSeek-V3",
    openai_api_key="************",
    openai_api_base="https://api.siliconflow.cn/v1",
    temperature=0.5,
    max_tokens=8000,
)
embeddings = HuggingFaceEmbeddings(
    model_name="D:/python/envs/lc/hfmodel/sentence-transformers/all-MiniLM-L6-v2",
)

# document块列表
loader = UnstructuredMarkdownLoader(file_path="output/c3.md")
documents = loader.load()
splitter = MarkdownTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
)
split_documents = splitter.split_documents(documents)

# 向量数据库,增加数据
vectorstore = Milvus(
    embedding_function=embeddings,
    connection_args={"uri": "http://192.168.1.101:19530"},
    collection_name="mt_coll",
    drop_old=True,
    auto_id=True,
    index_params={
        "index_type": "FLAT",
        "metric_type": "L2",
        "params": {"nlist": 1024},
    },
    search_params={"metric_type": "L2", "params": {"nprobe": 100}},
)
vectorstore.add_documents(split_documents)

# 提示模板
prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "根据上下文和对话历史回答问题。不知道的问题直接回答不知道。",
        ),
        MessagesPlaceholder(variable_name="chat_history"),
        (
            "human",
            """上下文:{context}。 问题:{question}。 回答:""",
        ),
    ]
)

# 格式化文档函数
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

# 创建基础RAG链
rag_chain = (
    {
        "context": itemgetter("question")
        | vectorstore.as_retriever(search_kwargs={"k": 2})
        | format_docs,
        "question": itemgetter("question"),
        "chat_history": itemgetter("chat_history") | RunnablePassthrough(),
    }
    | prompt
    | llm
    | StrOutputParser()
)

# 会话历史存储
store = {}
def get_session_history(session_id: str) -> ChatMessageHistory:
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]

# 使用RunnableWithMessageHistory包装RAG链
chain_with_history = RunnableWithMessageHistory(
    runnable=rag_chain,
    get_session_history=get_session_history,
    input_messages_key="question",
    history_messages_key="chat_history",
)

# 模拟对话
session_id = "user_123"
q1 = "茅台的产品介绍"
q2 = "控制面板上的Shutdown Faults,是什么故障,如何处理"

# 第一次查询
response = chain_with_history.invoke(
    {"question": q1},
    config={"configurable": {"session_id": session_id}},
)
print(f"Q: {q1}\nA: {response}")

# 第二次查询(依赖对话历史)
response = chain_with_history.invoke(
    {"question": q2},
    config={"configurable": {"session_id": session_id}},
)
print(f"Q: {q2}\nA: {response}")

总结

本文整理了 Milvus 向量数据库的核心概念、部署方式、基础操作、集合与字段设计、索引创建、数据插入、向量搜索和标量查询等内容。实际项目中,Milvus 适合用于大规模向量检索、RAG 知识库、多模态检索和语义搜索等场景;在使用时需要重点关注向量维度、索引类型、metric_type、集合加载状态、过滤条件以及数据持久化等关键配置。

相关推荐
摇滚侠1 小时前
01 基础语法 JavaScript 入门到精通全套教程
开发语言·javascript·ecmascript
aqi001 小时前
15天学会AI应用开发(三)把历史对话作为提示词会怎样
人工智能·python·大模型·ai编程·ai应用
大数据魔法师1 小时前
Streamlit(十八)- API 参考文档(十一)- 页面导航组件
python·web
赵渝强老师1 小时前
【赵渝强老师】崖山数据库的数据字典
数据库·oracle
code bean1 小时前
【LangChain】RunnableWithMessageHistory 完全指南(下):流式、截断与自定义
langchain
weixin_468466851 小时前
数据高效处理实战:从痛点解决到价值落地
大数据·python·自动化·数据处理
大大杰哥1 小时前
Java 日志框架详解:SLF4J + Logback 从入门到实战
java·开发语言·logback
java_cj1 小时前
MySQL 8.0 新特性深度解析:降序索引、Doublewrite Buffer 与 redo log 无锁优化
数据库·mysql