☰
ES09-ES向量检索-前置知识
2026/10/17 6:53:54 网站建设 项目流程

ES09-ES向量检索-前置知识

文章目录

  • ES09-ES向量检索-前置知识
  • 1-向量索引 / HNSW / ANN
  • 2-KNN / ANN
  • 3-BM25 + kNN + 稀疏向量
  • 4-RRF(Reciprocal Rank Fusion)倒数排名融合
  • 5-向量检索AI补充
    • 对话摘要
    • 一、场景故事:它在解决什么问题?
    • 二、核心机制:Python伪代码表达
    • 三、理解偏差:这些坑别踩
      • 偏差1:以为 `knn` 请求是"精确检索"
      • 偏差2:以为 kNN 和 ANN/HNSW 可以分开先后的学
      • 偏差3:以为 BM25 和向量检索互不相干
      • 偏差4:以为向量"空间形态"是存放形态,HNSW 只是检索时技巧
      • 易混淆点速查表
    • 四、记忆卡片:核心QA对
    • 五、知识网络:相似、互斥与路径
      • 🔗 相似知识:ANN 家族
      • ⚔️ 互斥/替代:精确 vs 近似
      • 📚 前置与后续
    • 关键收获

1-向量索引 / HNSW / ANN

1-KNN(k-nearest neighbor)->原始语义:精确的计算查询向量和每个空间向量的距离,找到top-k的最相近的空间向量

2-KNN(k-nearest neighbor)->业务语义:严格遵守KNN效率太低,【如何保证向量检索的效率】,期望达到【ANN】目标,具体使用【HNSW】算法-> 此时含义: 【KNN = 向量检索】

3-向量索引 / HNSW / ANN -> 说人话:提到ES的向量检索,KNN肯定是不太现实(精确,但效率太低了),我们的【目标是ANN(近似最近邻)】,那具体怎么做?->【实现ANN目标】的一个实现算法:【HNSW】分层可导航小世界图

4-ANN目标还有很多其他的算法

ANN(目标/问题范畴:近似地找最近邻) ├── HNSW (图结构,最主流) ├── IVF (倒排/聚类分桶) ├── PQ (乘积量化,压缩) ├── IVF+PQ (常组合使用,Faiss 经典) ├── Annoy (树结构) └── ...

5-层级关系梳理

向量检索:要取出最近的 k 个(KNN 任务) ↓ 精确做法 = 暴力扫描全库 → O(N·d),大规模太慢 ↓ 目标转向:ANN(近似最近邻)—— 用一点点召回率换巨大速度 ↓ ANN 是一类问题/目标,有多种实现算法: HNSW / IVF / PQ / Annoy / ... ↓ 其中 HNSW 是最主流的算法之一 (分层可导航小世界图:多层图,上层稀疏跳转,下层稠密精定位)

6-HNSW(Hierarchical Navigable Small World,分层可导航小世界图)

  • HNSW 是目前最主流、性能最好的 ANN 算法之一。Elasticsearch、Faiss、Milvus、Qdrant、pgvector 都用它。
  • HNSW 直观理解:多层"跳表 + 图"

7-HNSW优点

  • 查询快、精度高

  • 支持增量插入(不用重建全图)

  • 内存友好,工业界验证充分


8-HNSW缺点

  • 建索引慢、吃内存
  • 删除不友好(一般标记删除,定期重建)
  • 参数需要调优

2-KNN / ANN

严格意义上的KNN / ANN含义对比

1-KNN(k-nearest neighbor)精确检索

2-ANN(Approximate Nearest Neighbor,近似最近邻)

3-KNN精确检索 VS ANN近似最近邻

  • KNN(精确检索):拿查询向量和 100 万个向量逐一算距离,排序取 top 10。准确,但 O(N),100 万次计算,太慢。
  • ANN(近似最近邻):不保证 100% 找到真正的最近邻,但大概率找到非常接近的,速度提升几个数量级。

3-BM25 + kNN + 稀疏向量

1-BM25(关键词检索 / 稀疏词袋)->简单理解:就是ES的传统文本搜索

  • BM25 基于【词频 TF】和【逆文档频率 IDF】的查询排序->不同于向量数据库的语义匹配,是针对单词出现频率的检索方法
  • BM25 是传统全文检索的经典打分算法,Elasticsearch 默认的相关性打分
  • BM25 如果放在【向量视角】下:BM25 本质是稀疏向量(词表维度极高,绝大多数为 0)的点积。

2-kNN业务含义: 【KNN = 向量检索】

  • 向量检索先用 embedding 模型把文本/图像变成稠密向量(如 768 维,几乎每维都有值),再用前面讲的 HNSW/ANN 检索。
  • ES中的knn查询,就是向量检索,字段类型dense_vector。因为维度高,就是稠密向量

3- 稀疏向量(Sparse Vector / 学习型稀疏)

  • 既不是BM25低维的 词频检索 -> 简单理解:0维
  • 也不是KNN高维向量的 向量检索 -> 简单理解:高维
  • 稀疏向量介于 BM25 和稠密向量之间-> 简单理解:0维 < 维度 < 高维
    • 维度 = 词表大小(几万~几十万),和 BM25 一样稀疏。
    • 但每一维的权重是模型学出来的,不是 TF-IDF。
    • 代表:Elastic 的 ELSER、SPLADE。
  • 在 ES 里,用sparse_vector字段 +text_expansion查询(ELSER 场景)。

4-稀疏向量和BM25 的区别

BM25稀疏向量
权重来源统计公式(TF-IDF 类)神经网络学习
词项扩展无有(“汽车” 可激活 “vehicle” 维度)
可解释性强中
效果关键词准语义 + 关键词兼顾

5-稀疏向量和稠密向量的区别

稀疏向量稠密向量
维度词表级(几万+)几百~几千
每维含义对应词/term无直观含义
精确匹配强弱
语义泛化中强
存储稀疏存储,省空间定长稠密

4-RRF(Reciprocal Rank Fusion)倒数排名融合

  • RRF倒数排名融合-> 合并多个检索结果列表的算法,在向量数据库和混合检索(Hybrid Search)中非常常见

5-向量检索AI补充

对话时间:2026-10-15 20:46
核心概念:BM25、kNN、稀疏向量、ANN、HNSW 的三层关系

对话摘要

用户带着 4 条自己的理解来学习,核心误区是:把 ES 顶层knn请求当成"精确 kNN",并认为 kNN 可以和 ANN/HNSW 分开先后学。本次讲解建立了"问题(kNN)→ 策略(ANN)→ 结构(HNSW)"三层模型,并用对称视角统一了 BM25(稀疏空间 + 倒排索引)与向量检索(稠密空间 + HNSW 图)。


一、场景故事:它在解决什么问题?

📖 故事一:图书馆的两套找书哲学

你走进一座巨型图书馆,想找书。馆里有两种服务窗口:

  • A 窗口:你说几个关键词,管理员走到卡片柜前,抽出一摞卡片——每张卡片写着"这个词出现在哪些书的哪一页"。卡片柜是馆里最值钱的资产:有了它,管理员永远不用翻遍全馆的书,只看关键词指向的那几十本。
  • B 窗口:你递进去一本你喜欢的书,说"给我找气质最像的 10 本"。这里没有卡片柜可用——气质没法建关键词卡片。管理员只能拿着你的书,走遍每一个书架,和每一本比对。书少还行,书多了就是把管理员累死的节奏。

💡对应关系:

  • A 窗口的关键词卡片柜 ↔倒排索引(inverted index)
  • A 窗口的打分规则 ↔BM25
  • B 窗口的"气质比对" ↔稠密向量的 kNN

📖 故事二:B 窗口的两种干法——累死 vs 偷懒但聪明

图书馆 B 窗口被投诉太慢,馆方想出两套改造方案:

  • 方案甲(老实人方案):维持原样,一本不漏全比对。结果绝对准确,但 1000 万册书,每次查询都要比 1000 万次。
  • 方案乙(聪明人方案):重新装修图书馆——把书架组织成三层导航系统:顶层只挂几张大幅指示牌(“文学类→东馆”),中层挂区域图(“科幻→ 3 排”),底层才是每本书的精确位置。来人先在顶层顺着指示牌快速逼近目标区域,再逐层下沉,最后只在目标书架附近仔细比对一小圈。每次查询只比对几百本,速度提升一万倍;代价是偶尔会错过一本真正最像的书——它没在最后比对的那一小圈里。

💡对应关系:

  • 方案甲 ↔精确 kNN(暴力遍历)
  • 方案乙的"只比对一小圈" ↔ANN(近似最近邻,是一类策略的统称)
  • 方案乙的三层导航系统 ↔HNSW(分层图结构)
  • “偶尔错过真正最像的书” ↔近似(recall 损失)

二、核心机制:Python伪代码表达

# ==========================================================# 主题:BM25 / 精确kNN / ANN 三者其实是同一个问题的不同解法# 问题 = "在某个空间里,找出离查询最近的 k 个文档"# ==========================================================# ---------- 视角统一:BM25 就是"稀疏空间里的最近邻打分" ----------# 稀疏空间:维度 = 词表大小(如 3 万维),每篇文档绝大多数维度是 0defbm25_score(query_terms,doc):# 概念本质:sparse_dot(query稀疏向量, doc稀疏向量),只是每维权重按 BM25 公式算score=0.0forterminquery_terms:# 只遍历查询里的非零维度score+=idf(term)*tf_saturation(doc.tf(term))/doc_len_norm(doc)returnscore# 倒排索引 = 稀疏空间的加速结构:预先按"维度"组织好,跳过所有 0inverted_index={"elasticsearch":[doc1,doc3,doc7],"向量":[doc2,doc3],...}# ---------- 稠密空间:kNN 是"题目",有两种解法 ----------docs=[(doc_id,vector_768dim),...]defexact_knn(query_vec,k):"""精确解:暴力遍历,一个不漏。ES 里的面孔是 script_score。"""scored=[(cosine(query_vec,v),_id)for_id,vindocs]# 每篇都算 ← 全量代价returntop_k(scored,k)defann_knn(query_vec,k,num_candidates):"""近似解:先在图上'导航'逼近,只细看 num_candidates 个候选。 ES 里的面孔就是顶层 knn 查询。"""candidates=hnsw_search(query_vec,ef=num_candidates)# 图上贪心游走,只评估 100 个returntop_k(candidates,k)# ⚠️ 全库可能不止 100 个比它们近 → 这就是"近似"# ---------- HNSW:那个"三层导航系统" ----------classHNSW:# 第 0 层(底层):全量节点,边短 —— 街道级,负责精细比对# 第 1、2…层(向上):节点越来越稀疏,边越来越长 —— 高速路级,负责远距离跳转defsearch(self,query,ef):node=self.top_entry# 从顶层入口进(最高速的指示牌)forlayerinreversed(range(self.levels)):node=self.greedy_descend(node,query,layer)# 每层贪心走向更近的邻居returnself.local_search(node,query,ef)# 底层局部搜集 ef 个候选(=num_candidates)# ---------- 写入时 vs 查询时 ----------defindex_document(doc):store_raw_vector(doc.vector)# ① 原始向量本体,按行存(doc values)hnsw_graph.insert(doc.vector)# ② 写入时就构建 HNSW 图的节点和边 ← 索引结构!# 类比:倒排索引之于 BM25 = HNSW 图之于稠密向量 kNN

💡代码要点:

  1. 统一视角:BM25 和 kNN 都是"找最近的 k 个",只是空间不同。
  2. 加速结构对称:稀疏空间靠倒排索引跳过 0 维度;稠密空间靠 HNSW 图跳过大部分节点。
  3. num_candidates是分水岭:出现它 = 只评估一小部分文档 = ANN 铁证。
  4. 图是写入时建的:dense_vector设index: true(8.x 默认),每个 Lucene segment 一张 HNSW 图。
  5. 近似的有损性:num_candidates越大召回越准但越慢;极限等于全库时退化为精确 kNN。

三、理解偏差:这些坑别踩

偏差1:以为knn请求是"精确检索"

❌ ES 顶层knn查询底层是 HNSW(ANN 近似)。num_candidates: 100意味着每分片只细看 100 个候选。
✅ ES 里的精确 kNN 长这样:

POSTmy-index/_search{"query":{"script_score":{"query":{"match_all":{}},"script":{"source":"cosineSimilarity(params.qv, 'title_vector') + 1.0","params":{"qv":[0.11,-0.02,0.90]}}}}}

对每篇文档计算相似度,无num_candidates。
🧠 接口名knn是问题域命名,实现走的是近似策略——名字与实现分属两层。
🧪 自测:num_candidates=100 而全库 1000 万篇时,其余文档的相似度算过吗?没算过 = 近似。

偏差2:以为 kNN 和 ANN/HNSW 可以分开先后的学

❌ 它们不是并列知识,而是三个层次:kNN=问题,ANN=求解策略(一族算法统称),HNSW=具体数据结构。
✅ 可以延后学 HNSW 的内部原理,但第一天就必须知道"ES 的 knn 接口 = ANN = HNSW 近似检索"。
🧠 教材按"精确→近似"历史顺序讲,而 ES 用户从 API 切入,第一行代码就站在"近似"层。
🧪 自测:能否脱口而出"knn=策略+结构层的近似解;script_score=问题层的精确解"?

偏差3:以为 BM25 和向量检索互不相干

✅ 两者都是最近邻检索,只是空间不同,对称性工整:

BM25 / 稀疏向量 kNN / 稠密
空间词表维度(数万维,极稀疏)模型维度(768/1024 维,稠密)
打分BM25 公式cosine / dot / L2
加速结构倒排索引HNSW 图

🧠 ES 文档把match和knn分在不同章节,掩盖了数学统一性。
🧪 自测:为什么 BM25 不需要扫全库而 kNN"想"扫全库?(稀疏向量只有查询词维度非零,倒排索引直接定位;稠密向量每维非零,只能靠图。)

偏差4:以为向量"空间形态"是存放形态,HNSW 只是检索时技巧

✅ 768 维空间是数学抽象;物理上只存 ① 向量本体(doc values,供精确打分)② 写入时构建的 HNSW 图(节点=向量,边=导航链接)。HNSW 与倒排索引同级,是索引结构,index: true时即开始建。
🧠 数学空间 ≠ 物理存储。物理世界只有图、边和浮点数列。
🧪 自测:text字段写入时建倒排索引;dense_vector+index:true写入时建 HNSW 图——两个答案同级。

易混淆点速查表

维度kNN(问题)ANN(策略)HNSW(结构)
它是什么数学定义:找最近的 k 个一类近似解法的统称ANN 的一个具体算法/索引
精确性题目本身要求精确接受漏报换速度有 recall 损失,可调
在 ES 的位置script_score(精确版)无直接对应knn查询的底层实现
维度knum_candidates
含义最终返回的近邻数每分片(每 segment)细看的候选数
关系结果的"出口"过程的"探照灯",必须 ≥ k
调大效果返回更多更准、更慢

四、记忆卡片:核心QA对

#问题答案
1定义:BM25、kNN 统一视角下是什么?都是最近邻检索:BM25 在稀疏空间(词表维度)打分,kNN 在稠密空间(模型维度)打分。
2机制:ES 顶层knn查询的底层是什么?HNSW 图上的 ANN 搜索。num_candidates控制每分片细看的候选数,k是最终返回数。
3机制:ES 里"精确 kNN"怎么写?script_score+cosineSimilarity,对每篇文档打分——暴力遍历,无num_candidates。
4场景:什么时候用精确 kNN?什么时候用 ANN?数据量小(千级)、召回必须 100% → 精确;百万级以上、可接受少量漏报 → ANN。
5权衡:ANN 付出什么代价?召回损失 + 建图/内存开销;调大num_candidates换召回但变慢。
6区分:kNN vs ANN vs HNSW?问题 → 策略 → 数据结构三层嵌套。
7区分:倒排索引和 HNSW 图的关系?对偶对称:稀疏空间(BM25)与稠密空间(kNN)各自的加速结构,均写入时构建。
8边界:num_candidates= 全库会怎样?ANN 退化为精确 kNN——精确与近似是一条连续光谱。

五、知识网络:相似、互斥与路径

🔗 相似知识:ANN 家族

对比维度HNSWIVFLSH
核心思想分层图上贪心导航聚类分桶,只搜最近桶哈希把近邻映射同桶
最佳场景通用首选(ES/Lucene 默认)内存受限、离线批量超大规模分布式
选择依据ES 用户基本无选择——Lucene 只实现 HNSWFaiss/Milvus 常见特殊规模场景

⚔️ 互斥/替代:精确 vs 近似

对比维度精确 kNN(script_score)ANN kNN(knn 查询)
核心思想一个不漏全算图上导航只看局部
最佳场景小数据集 / top-k 必须绝对正确大数据集 / 接受 ~99% 召回
选择依据数据量 × 召回要求;注意 filter 语义不同(script_score 先过滤再全量打分;knn 图搜途中/之后过滤)

📚 前置与后续

  • 前置:余弦相似度/向量空间模型;倒排索引 + TF-IDF→BM25;Lucene segment 概念(图是 per-segment 的)
  • 后续:HNSW 内部原理(m、ef_construction);混合检索 + RRF;学习型稀疏向量 ELSER/SPLADE(sparse_vector 字段,仍走倒排索引);向量量化(int8/BBQ)
  • 最佳搭档:BM25 + kNN + RRF 混合检索——关键词保精确命中,向量保语义泛化

关键收获

  • 三个词分属三层:kNN 是问题,ANN 是策略,HNSW 是结构;ES 的knn接口 = ANN 实现 = HNSW 图。
  • 对称统一视角:倒排索引之于 BM25 = HNSW 图之于稠密 kNN——都是写入时构建的加速结构。
  • ES 里精确 kNN 的真身是script_score;带num_candidates的knn一定是近似。
  • 精确与近似是连续光谱:num_candidates拉满 = 精确,调小 = 快但可能漏。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询