news 2026/10/1 2:47:46

搜索系列 · 第 03 篇——核心原理:倒排索引与 BM25

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
搜索系列 · 第 03 篇——核心原理:倒排索引与 BM25

倒排索引 · 分词映射 · 相关性打分 · 段管理

目 录

一、导读

二、倒排索引原理

2.1 正排 vs 倒排

2.2 倒排索引结构

2.3 示例

三、分词器与映射

3.1 Analyzer 处理流程

3.2 常见分词器

3.3 映射:text vs keyword

四、BM25 相关性打分

4.1 从 TF-IDF 到 BM25

4.2 BM25 公式

4.3 参数含义

五、近实时写入与段管理

5.1 写入路径

5.2 段合并策略

5.3 主分片与副本的一致性

六、聚合分析与本篇小结

6.1 三类聚合

6.2 本篇小结

一、导读

本讲深入 Elasticsearch 内核:检索为何快(倒排索引结构)、文本如何被拆解(分词器与映射)、结果如何排序(BM25 相关性打分)、写入如何高效(近实时与段管理)。理解这些,是建模映射、优化查询与调优性能的基础。

二、倒排索引原理

2.1 正排 vs 倒排

关系库与普通存储采用「正排索引」:以文档为核心记录「文档包含哪些词」,查询某词需逐条扫描。倒排索引反其道而行,以「词项」为核心记录「每个词出现在哪些文档」。可用书籍类比:正排像目录(章节→页码),倒排像书尾索引页(关键词→页码列表),查词直接翻对应页。

2.2 倒排索引结构

倒排索引由三部分协同组成:

组成

内容

作用

词典 Dictionary

所有不重复词项,支持 FST 压缩

定位词项倒排链

倒排表 Posting List

包含该词的文档 ID 列表

确定命中文档

位置表 Position

词在文档内的词频、位置与偏移

打分、短语、高亮

每个词项还会记录文档频率(df)等统计信息,供相关性打分使用。

2.3 示例

// 文档

doc1: "NoSQL 实战"

doc2: "Elasticsearch 实战"

// 倒排索引(词项 -> 文档列表)

NoSQL -> [1]

实战 -> [1, 2]

Elasticsearch -> [2]

// 查询"实战"直接定位文档 1、2,无需全表扫描

三、分词器与映射

3.1 Analyzer 处理流程

文本在写入前先经「分词器」(Analyzer)处理,由三阶段流水线构成:字符过滤器(Character Filter,如去 HTML 标签)→ 分词器(Tokenizer,按规则切词)→ 词项过滤器(Token Filter,如转小写、去停用词、同义词)。英文与中文的分词策略差异明显。

3.2 常见分词器

分词器

适用

说明

standard

通用

按 Unicode 边界切分,英文友好

simple

英文

按非字母字符切分并转小写

keyword

不分词

整段作为一个词项

ik

中文

中文分词器(smart / max_word)

whitespace

特殊

仅按空白切分

3.3 映射:text vs keyword

映射(Mapping)定义字段类型与分词策略,是「数据的 DNA」:text 字段会分词并建立倒排索引,用于全文检索;keyword 字段不分词、按原值精确匹配,用于过滤、排序与聚合。设计映射时需按查询方式决定用 text 还是 keyword,常用 multi-fields 同时保留两种视图。

PUT /article/_mapping

{ "properties": {

"title": { "type": "text", "analyzer": "ik_max_word" },

"tag": { "type": "keyword" }

} }

四、BM25 相关性打分

4.1 从 TF-IDF 到 BM25

早期 Lucene 使用 TF-IDF 打分,长文档易因词频累积获得不公平高分。Elasticsearch 5.x 起默认改用 BM25(Best Match 25),在词频与文档长度之间取得平衡,成为相关性排序的默认机制。

4.2 BM25 公式

BM25 对每个查询词累加得分,核心公式:

score(D,Q) = Σ IDF(qi) × (fi × (k1 + 1))

/ (fi + k1 × (1 - b + b × |D| / avgdl))

IDF(qi) = ln(1 + (N - df + 0.5) / (df + 0.5))

# k1=1.2 控制词频饱和,b=0.75 控制长度归一化

4.3 参数含义

  • IDF:逆文档频率,词越稀缺得分越高,抑制高频通用词。
  • fi:词在文档中的出现频率,词频越高得分越高(但会饱和)。
  • |D| / avgdl:文档长度与平均长度之比,惩罚「用长文档稀释关键词」的情况。
  • k1、b:调节参数,ES 默认分别为 1.2 与 0.75。

生产可用 Function Score 或自定义 similar,叠加业务权重(如新品加权、会员加权)微调排序。

五、近实时写入与段管理

5.1 写入路径

写入先进内存缓冲并追加 translog,约 1 秒(refresh)生成可搜索新段;flush 将段持久化落盘并清空 translog。不可变段 + 删除标记实现更新,避免原地修改的并发锁与磁盘碎片。

5.2 段合并策略

随时间累积大量小段,后台采用分层合并(Tiered Merge)按规模分级合并,减少段数、提升检索与稳定性。合并触发条件通常包括:段数量达到阈值、删除文档占比超过阈值、或某段过大。合并瞬时会产生额外 I/O,生产常结合索引生命周期(ILM)与滚动索引错峰处理。

5.3 主分片与副本的一致性

写入由主分片负责并同步到副本;检索默认在主、副本间负载均衡。通过 wait_for_active_shards 可控制至少多少活跃副本确认写入,在可用性与一致性之间权衡。

六、聚合分析与本篇小结

6.1 三类聚合

ES 内置三类聚合支撑实时分析:

类别

代表

用途

指标 Metric

avg / sum / max / percentiles

数值统计

桶 Bucket

terms / date_histogram / range

分组与时间分桶

管道 Pipeline

bucket_script / derivative

基于聚合再加工

6.2 本篇小结

本讲厘清 ES 内核四块基石:倒排索引以「词项→文档」映射换来毫秒级检索;分词器与映射决定文本如何被拆解与检索;BM25 在词频与文档长度间平衡出相关性排序;近实时刷新与分层段合并支撑高效写入。理解这些原理,是后续部署、选型与调优的基础。

下一篇进入部署实操,在内网环境落地 Elasticsearch 集群(含高可用与一键脚本)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 2:46:56

ST32 与 ET200SP 通讯翻车后,我总结了这份踩坑指南

西门子PLC SMART G2和ET200SP调通通讯需要多久,相信很对PLC工程师都会说分分钟搞定。我也一样,信誓旦旦的给同事说等我一下,最多10分钟,可这调通之路折腾了我2天时间。给大家分享我的踩坑之路。以为简简单单,5分钟搞定…

作者头像 李华
网站建设 2026/10/1 2:46:38

初识C语言:函数的定义、参数、调用

1.什么是函数(1)定义:函数即子程序,是一个大型程序中的某部分代码,由一个或多个语句块组成。负责完成某项特定的任务,与其他代码相比,有相对的独立性2.C语言中的函数分类(1)库函数:C语言自带的函数总结C语言…

作者头像 李华
网站建设 2026/10/1 2:46:33

AI服务测试离线化:JevTape实现真实LLM决策录制与回放

1. 项目概述:为什么“录一次真实 AI 决策,以后测试全离线跑”这件事值得专门造个工具?JevTape 这个名字乍看像 Java Tape(磁带)的组合,但实际它指向一个非常具体、非常痛的工程实践场景:AI 服务…

作者头像 李华
网站建设 2026/10/1 2:44:18

RomM BIOS 固件配置:GBA 模拟器黑屏一次修好

RomM BIOS 固件配置:GBA 模拟器黑屏一次修好 【免费下载链接】romm A beautiful, powerful, self-hosted ROM manager and player. 项目地址: https://gitcode.com/GitHub_Trending/rom/romm RomM 刚跑起来,点开一个 GBA 游戏,画面停在…

作者头像 李华
网站建设 2026/10/1 2:43:48

运动模糊的本质与量化控制:从物理原理到工程实践

1. 运动模糊不是“糊”,而是光与时间的精确契约你有没有拍过跑步的人,结果照片里人影拉出一道虚线?有没有录过快速挥动的球拍,回放时发现球体边缘像被橡皮擦蹭过一样发毛?甚至用手机扫二维码,手一抖&#x…

作者头像 李华