从零了解Qdrant向量数据库

1. 何为向量数据库

通俗来说,向量数据库(Vector Database)是一种专门存储和查询「向量数据」的数据库,核心能力是解决计算机对「非结构化数据」的语义理解和快速检索问题。如果你对机器学习或 AI 应用感兴趣,它可能是一个绕不开的关键技术。下面用最接地气的方式带你理解。

1.1 什么是向量?为什么需要向量数据库?

1. 向量:非结构化数据的「数字指纹」
  • 非结构化数据:像图片、文本、音频、视频这类没有固定格式的数据(比如你手机里的照片、聊天记录中的文字),传统数据库(如 MySQL)很难直接处理它们的内容。

  • 向量(Vector) :通过 AI 模型(如 NLP 中的 BERT、图像中的 ResNet)将非结构化数据「编码」成一组高维数字(例如一个 1024 维的数组),这些数字反映了数据的语义特征,类似人类对数据的「理解」。
    举例

    • 文本 "猫和狗" 编码成向量后,可能和 "宠物" 的向量距离很近,和 "汽车" 的向量距离很远。
    • 图片中的猫图片编码成向量后,和其他猫的图片向量距离近,和狗的图片向量距离远。
2. 传统数据库的困境:无法理解「相似性」
  • 传统数据库擅长处理结构化数据(如 "年龄 = 25 岁""标签 = 科技"),但无法直接比较两个向量的「相似程度」。
    比如:你想在 100 万张图片中找到 "和这张猫图相似的图片",传统数据库需要逐个对比像素(效率极低),而向量数据库可以通过数学公式(如余弦相似度、欧氏距离)快速计算向量间的距离,找出最相似的结果。

1.2 向量数据库的核心能力:存向量、查相似、加过滤

向量数据库的功能可以用三个关键词概括:

1. 存储向量:海量高维数据的仓库
  • 专门优化存储高维向量(如 128 维、768 维、1536 维),支持每秒数万甚至数十万向量的写入。
    场景:抖音每天需要存储上亿条视频的向量特征,用于推荐系统。
2. 相似性搜索:从千万向量中秒级找 "同类"
  • 使用近似最近邻算法(ANN,Approximate Nearest Neighbor) ,比如 HNSW、IVF、NSW 等,将搜索复杂度从暴力搜索的 O (N) 降低到 O (logN),实现快速检索。
    举例

    • 输入一个文本 "推荐一部科幻电影",向量数据库能快速找到语义相似的文本向量(如 "求推荐类似《星际穿越》的电影")。
    • 原理类似:在一个巨大的 "数字地图" 中,通过算法快速定位到离查询向量最近的几个点。
3. 标量过滤:给向量加 "标签筛子"
  • 向量数据库通常支持将向量与结构化数据(称为 Payload,如标签、时间戳、数值等)结合存储,查询时可以先用结构化条件过滤,再做相似性搜索。
    举例

    • 搜索 "最近一周内发布的、点赞超过 10 万的、类别为'科技'的相似文章":

      1. 先用 Payload 过滤出时间在一周内、点赞 > 10 万、类别 = 科技的向量;
      2. 再在这些向量中找与查询文本最相似的结果。

1.3 为什么说向量数据库是 AI 的 "基础设施"?

1. 连接非结构化数据与 AI 模型的桥梁
  • AI 模型(如大语言模型 LLM)输出的是向量(如文本嵌入),向量数据库可以存储这些向量,并支持快速检索,形成「数据输入→模型编码→向量存储→相似查询→结果输出」的闭环。
    典型场景

    • 智能客服:将知识库文本转为向量存储,用户提问时通过向量数据库找到最相似的问题解答,提升响应效率。
    • 推荐系统:将用户行为(点击、观看记录)转为向量,匹配相似内容或用户,实现个性化推荐。
2. 解决传统数据库在 AI 时代的短板
  • 传统数据库处理非结构化数据需要复杂的预处理(如关键词提取、规则匹配),无法捕捉语义细节;向量数据库直接基于数据的语义特征(向量)进行检索,更贴近人类理解。
    对比

    • 传统搜索:搜索 "电脑坏了怎么办",可能匹配到包含 "电脑""坏了" 关键词的文章,但可能遗漏 "计算机故障解决" 这类同义表达。
    • 向量搜索:通过语义向量匹配,能找到所有表达 "设备故障求助" 的内容,无论关键词是否一致。

2. 从Qdrant数据库了解向量数据库的设计

向量数据库的三大核心需求是:存向量快、查相似准、过滤条件灵活

我们都知道,数据库的查询和过滤主要靠的就是各自数据索引的设计,在Qdrant中,通过HNSW索引 加速向量数据的相似性查询,通过Payload索引实现数据的条件查询。

2.1 什么是HNSW索引

在向量数据库中,HNSW(Hierarchical Navigable Small World Graph,层次化可导航小世界图) 是最核心的向量索引算法之一。它的设计灵感来源于 "导航"------ 就像你开车时先用高速路快速定位大致区域,再用城市道路精细找目的地,HNSW 通过分层图结构,让计算机能在高维向量空间中快速找到 "最相似" 的向量。

一、HNSW 的核心思想:分层图结构,像导航一样找向量

要理解 HNSW,先想象一个场景:你要在一个陌生城市找一家叫 "街角咖啡店" 的小店。最优策略是:

  1. 先看地图的 "高层"(如卫星图),找到咖啡店所在的区;

  2. 再看 "低层"(如街道图),在区内找具体位置。

HNSW 的设计逻辑完全类似:

  • 分层图结构:将向量组织成多层 "图",高层稀疏、低层密集;
  • 导航式搜索:从高层快速定位目标区域,再逐层向下精细搜索。
1. 高层(顶层):快速定位 "大区域"
  • 特点:节点稀疏,每个节点连接的边少,但边的 "跨度" 大(类似高速路)。
  • 作用:通过少量节点快速缩小搜索范围。例如,在 100 万向量中,高层可能只有 100 个节点,覆盖整个向量空间的大区域。
2. 中层(中间层):缩小到 "小区域"
  • 特点:节点密度增加,边的跨度减小(类似城市主干道)。
  • 作用:在高层定位的大区域内,进一步缩小到更精确的子区域。
3. 底层(第 0 层):精细搜索 "具体点"
  • 特点:节点最密集,边的跨度最小(类似小区道路)。
  • 作用:在中层定位的子区域内,遍历所有邻近节点,找到最相似的向量。

三、HNSW 的构建过程:如何从向量生成 "导航图"?

HNSW 的索引构建是一个 "逐层插入、动态建图" 的过程,核心步骤如下:

步骤 1:为每个向量分配 "楼层"(层数)

每个向量(节点)的层数由随机概率决定(通常服从几何分布):

  • 层数越高,节点越少。例如,层数l的概率为(p^l)(p通常取 0.5),意味着约 50% 的节点在第 0 层,25% 在第 1 层,12.5% 在第 2 层,以此类推。
  • 高层节点一定存在于所有更低层(如第 2 层的节点也在第 1 层和第 0 层)。
步骤 2:逐层插入节点,建立 "导航边"

从底层(第 0 层)开始,逐层向上插入节点,每层独立建图:

  • 插入第k层节点v

    • 在当前层中,找到与v最相似的m个邻居(m是每层的最大边数,如 16);
    • 建立v与这些邻居的双向边(类似在道路图中标记 "从 A 到 B 有一条路")。
  • 跨层连接:同一节点在不同层的实例通过 "垂直边" 连接(如第 2 层的v连接到第 1 层的v)。

关键参数:控制图的 "密度" 与 "质量"
  • m(每层最大边数):控制图的密度。m越大,图越密集,搜索速度越快,但内存占用越高(默认 16)。
  • (ef_{\text{construct}})(构建时的探索因子):插入节点时,在当前层搜索的候选邻居数。(ef_{\text{construct}})越大,找到的邻居越精确,索引质量越高,但构建时间越长(默认 100)。

四、HNSW 的查询过程:如何从查询向量 "导航" 到最近邻?

假设你要找与查询向量q最相似的k个向量,HNSW 的搜索流程如下:

步骤 1:从最高层 "入口节点" 开始搜索

最高层的入口节点是一个虚拟起点(类似城市的 "中心广场"),搜索从这里出发。

步骤 2:逐层向下 "粗筛"
  • 在当前层,找到与q最相似的节点u(通过遍历u的邻居,比较距离);
  • 如果当前层不是底层,跳转到u在下层的实例,重复此步骤;
  • 直到到达底层(第 0 层),此时已缩小到q附近的小区域。
步骤 3:底层 "精细搜索"

在底层,维护一个优先队列(按距离排序),不断扩展当前节点的邻居,直到满足终止条件(如队列大小达到k,或剩余节点距离都大于队列中最远节点的距离)。

关键参数:控制搜索的 "速度 - 精度" 平衡
  • ef(查询时的探索因子):底层搜索时,优先队列的最大容量。ef越大,搜索越精确(召回率越高),但延迟越长(默认等于(ef_{\text{construct}}))。

2.2 什么是 Payload 索引?

在向量数据库中,向量(Vector) 是核心 ------ 它通过数值化的特征向量表示数据(如图像、文本、音频等),而 Payload 则是向量的 "元数据伴侣",用于存储与向量相关的描述性信息。例如:

  • 一篇文档的向量对应语义特征,Payload 可包含标题、作者、发布时间、标签等;

  • 一张图片的向量对应视觉特征,Payload 可包含文件名、拍摄设备、分类标签等。

Payload 的核心作用

  • 补充语义信息:向量本身是抽象的数值,Payload 赋予其业务含义;

  • 精准过滤与排序:在向量相似性搜索基础上,通过 Payload 条件(如 "标签 = 科技""时间 > 2023")缩小结果范围或调整优先级。

但问题来了:当数据量庞大时,如何快速根据 Payload 进行筛选?这就需要 Payload 索引(Payload Index)

一、Payload 索引的常见类型与实现原理

根据 Payload 的数据类型和查询需求,索引方式可分为以下几类:

1. 等值查询索引:快速匹配 "等于" 条件

适用场景 :筛选标签(如category=sports)、状态字段(如status=active)等。
实现方式

  • 哈希表(Hash Table) :将字段值映射到哈希桶,查询时直接通过哈希值定位数据,时间复杂度接近 O (1)。

    • 优点:查询速度极快,适合高频等值查询;
    • 缺点:不支持范围查询,且哈希冲突可能影响性能。
  • B 树 / B + 树 :按字段值排序构建树结构,支持等值查询和范围查询(如id>100)。

    • 优点:有序存储,范围查询效率高;

    • 缺点:写入时可能产生树的分裂 / 合并,影响性能。

示例 :在 Qdrant 中,对user_id字段建立 B 树索引后,查询user_id=123可直接通过树结构快速定位对应向量条目。

2. 范围查询索引:处理数值与时间的 "区间筛选"

适用场景 :数值范围(如price>500)、时间范围(如created_at BETWEEN '2023-01-01' AND '2023-12-31')。
实现方式

  • B + 树:天然支持范围查询,叶子节点按顺序存储数据,可快速扫描区间内的所有值。

  • 跳表(Skip List) :一种有序的数据结构,通过多层索引提升范围查询效率,实现复杂度低于平衡树。

示例 :在日志分析场景中,Payload 包含timestamp字段,通过 B + 树索引可快速筛选最近一周的日志向量。

3. 全文搜索索引:让文本查询更智能

适用场景 :在 Payload 的文本字段中搜索关键词(如文档标题中的 "人工智能")。
实现方式

  • 倒排索引(Inverted Index) :将文本拆分为单词(Token),记录每个单词出现的文档列表(Postings List)。

    • 优点:支持模糊查询、短语查询、布尔逻辑(AND/OR/NOT);
    • 缺点:需要预先分词,占用存储空间较大。
  • 前缀树(Trie) :用于快速匹配前缀(如搜索 "app" 时匹配 "apple""application"),但对长文本效率较低。

示例 :在 Qdrant 中,对content字段建立倒排索引后,可执行title:*深度学习*的查询,匹配所有标题包含 "深度学习" 的文档向量。

4. 复合索引:多条件查询的 "组合拳"

当查询涉及多个 Payload 字段时(如category=tech AND price<1000),需要 复合索引 将多个条件组合优化:

  • 联合索引 :按字段顺序构建索引(如(category, price)),优先过滤category,再在子集内过滤price
  • 谓词下推(Predicate Pushdown) :将过滤条件下推到存储层,减少参与计算的向量数量,提升查询效率。
二、Payload 索引与向量索引的协同:1+1>2 的查询逻辑

向量数据库的典型查询流程通常分为两步:

  1. 向量层检索:通过向量索引(如 HNSW)找到相似向量的候选集;

  2. Payload 层过滤:通过 Payload 索引对候选集进行元数据条件筛选。

示例:搜索 "与《AI 未来》语义相似,且标签为'技术'、发布时间在 2024 年以后的文档":

  • 首先用 HNSW 索引找到与《AI 未来》向量最相似的 Top 100 文档;

  • 再通过 Payload 索引过滤出tag=技术publish_time>2024的结果,最终返回符合条件的 Top 10。

这种 "先向量相似性,后元数据过滤" 的模式,让向量数据库既能处理语义匹配,又能满足业务逻辑的精准筛选。

三、Payload 索引的挑战与优化方向
  1. 索引膨胀问题:过多索引会占用存储空间,需平衡查询速度与存储成本(如仅对高频查询字段建索引);
  2. 动态更新性能:频繁写入时,索引维护(如 B 树分裂、倒排索引更新)可能成为瓶颈,可通过批量写入或异步更新优化;
  3. 多模态查询优化 :结合向量索引与 Payload 索引的查询计划优化(如 Qdrant 的filterscore参数协同)。
四、Qdrant 中的 Payload 索引实践

Qdrant 作为高性能向量数据库,对 Payload 索引的支持具有以下特点:

  • 灵活的数据类型:支持数值、字符串、布尔值、数组等多种 Payload 字段;

  • 高效的过滤语法 :通过filter参数直接使用 JSON 表达式进行条件筛选(如{"field": "tag", "match": "tech"});

  • 索引自动管理:默认对高频查询字段自动优化,开发者无需手动创建索引,降低使用门槛。

例如,在 Qdrant 中存储商品向量时,Payload 可包含price(数值)、category(字符串)、in_stock(布尔值),查询时可通过 Payload 索引快速过滤出 "价格 < 2000 元、属于电子产品且有库存" 的商品,再结合向量相似性排序返回结果。

相关推荐
SimonKing13 分钟前
手搓MCP客户端动态调用多MCP服务,调用哪个你说了算!
java·后端·程序员
写bug写bug28 分钟前
分布式锁的使用场景和常见实现(上)
分布式·后端·面试
Ali酱36 分钟前
2周斩获远程offer!我的高效求职秘诀全公开
前端·后端·面试
小乌龟不会飞2 小时前
【SpringBoot】统一功能处理
java·spring boot·后端
刘小吉2 小时前
java net 配置局域网受信任的https
后端
考虑考虑2 小时前
JPA中的EntityGraph
spring boot·后端·spring
coolflyr_reg2 小时前
禅道集成Firebase PHP-JWT
后端
似水流年流不尽思念2 小时前
常见的排序算法有哪些?它们的平均时间复杂度是多少?
后端·算法
孟永峰_Java3 小时前
MySQL 组合IN查询:你的索引为什么罢工了?
后端
ruokkk3 小时前
一个困扰我多年的Session超时Bug,被我的新AI搭档半天搞定了
javascript·后端·架构