从零了解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 元、属于电子产品且有库存" 的商品,再结合向量相似性排序返回结果。

相关推荐
写bug写bug30 分钟前
彻底搞懂 RSocket 协议
java·后端
就是我30 分钟前
轻松管理Linux定时任务:Cron实用教程
linux·后端
橘子青衫34 分钟前
深入理解Callable与Future:实现Java多线程中的异步任务处理
java·后端
bobz9651 小时前
libvirt 相关 sock 整理
后端
Asthenia04122 小时前
ElasticSearch8.x+SpringBoot3.X联调踩坑指南
后端
gou123412342 小时前
【Golang进阶】第八章:并发编程基础——从Goroutine调度到Channel通信实战
开发语言·后端·golang
程序小武2 小时前
python编辑器如何选择?
后端·python
陈随易2 小时前
薪资跳动,VSCode实时显示今日打工收入
前端·后端·程序员
失乐园2 小时前
电商/物流/IoT三大场景:用MongoDB设计高扩展数据架构的最佳实践
java·后端·架构
五行星辰2 小时前
Spring AI 实战:用 Java 搞 AI,从此告别调参侠
java·后端