全文检索引擎:Lucene · BM25 · Segment · Elasticsearch NRT
搜索引擎架构 把倒排之上的系统设计与集群陷阱讲清了;存储工程·索引结构 把倒排当作众多索引之一介绍了;日志栈选型 在可观测场景里比较了 ES 与 Loki / ClickHouse。中间仍缺一层:一条文档如何经 Analyzer 进入 Lucene Segment,BM25 如何在 postings 上打分,Elasticsearch 的 refresh / flush / translog 各自保证什么。
本系列以 Apache Lucene 9.x/10.x 为库内核主线、Elasticsearch 8.x 为分布式服务层,写:
- Document / Field / Term / Postings / DocValues 与分析链 Analyzer。
- FST 词典、postings codec、BM25 Similarity、IndexWriter 与 MergePolicy。
- Boolean 查询执行、Collector、以及排序/聚合为何走 DocValues。
- Index / Shard / Replica、近实时 refresh、translog 持久化边界与协调节点查询路径。
- 混合检索(BM25∩向量)接口边界、OpenSearch 分叉、排障与选型决策树。
系列状态:已完成(2026-07-15)。 全 18 篇。规划见 PLAN.md。
版本锚定:Lucene 9.x / 10.x;Elasticsearch 8.x Reference;OpenSearch / Solr 在对照篇标注文档版本。本机实验以单节点为主,见 PLAN 实验台账;不伪造千节点集群吞吐。
适合谁看
- 聪明的学生 / 研究生:能跟公式与系统图,要建立「一条 index / search 怎么走」的生产直觉。
- 搜索 / 平台工程师:运维 ES,要从延迟与可见性反推到 Segment / refresh / circuit breaker。
- 从 architecture/42 下沉的读者:已有架构故事,缺库内核与 NRT 机制。
- 从 RAG / llm-infra 过来的读者:会用稀疏召回,要看引擎侧 postings 与混合接口。
- 先修:搜索引擎架构 或 索引结构;向量检索引擎 在读第 15 篇前可选。
在知识栈中的位置
| 层 | 系列 | 本系列关系 |
|---|---|---|
| 倒排入门 / 多索引 | storage/29 | 第 1–2 篇外链 |
| 搜索系统设计 | architecture/42 | 第 1、11、17 篇对读,不复述故事 |
| 全文引擎内核 | 本系列 | Lucene Segment + ES NRT |
| RDBMS 倒排 | postgresql-kernel/16 GIN | 第 4、18 篇对照 |
| 向量引擎 | vector-engine | 第 15 篇混合边界 |
| RAG 应用 | llm-infra/17–18 | 第 6、15、18 篇回链 |
| 日志栈选型 | observability/08 | 第 18 篇回链 |
一、这个领域最值得关注的 5 个问题
倒排在 Lucene 里具体落成哪些文件与编解码? → 第 2–5、10 篇:Terms、postings、DocValues、stored fields 各解决哪类访问。
一条索引文档如何经 Analyzer 进入可搜 Segment?soft delete / merge 如何改可见性? → 第 3、7–8 篇:TokenStream、IndexWriter flush、liveDocs。
BM25 与 Boolean 查询如何在 postings 上相交、打分、截断? → 第 6、9 篇:Similarity、Scorer、Collector / TopDocs。
ES 的 refresh / flush / translog 各自保证什么?近实时可读差在哪一层? → 第 11–13 篇:可搜窗口 vs 持久化 vs 崩溃恢复。
何时上 ES,何时 PG GIN / ClickHouse / 向量引擎? → 第 15–18 篇:混合接口、分叉对照与决策树。
二、篇目依赖关系与推荐阅读路径
flowchart TD
A["01 全文引擎全景"] --> B["02 文档模型"]
B --> C["03 Analyzer"]
B --> D["04 FST 词典"]
D --> E["05 Postings codec"]
E --> F["06 BM25"]
C --> G["07 IndexWriter NRT"]
G --> H["08 Merge 删除"]
F --> I["09 查询执行"]
E --> J["10 DocValues"]
A --> K["11 Shard Replica"]
G --> L["12 refresh translog"]
K --> L
L --> M["13 查询路径"]
J --> N["14 聚合 mapping"]
M --> N
F --> O["15 混合检索"]
K --> P["16 OpenSearch Solr"]
N --> Q["17 排障"]
O --> R["18 选型"]
P --> R
Q --> R
| 路径 | 篇目 | 适合 |
|---|---|---|
| 必读核心 | 1 → 2 → 5 → 6 → 7 → 12 → 13 → 18 | 快速建立坐标系 |
| Lucene 库调优 | 2 → … → 10 → 17 | 嵌入式检索 / 插件开发 |
| 运维 ES 集群 | 1 → 11 → 12 → 13 → 14 → 16 → 17 → 18 | 平台运维 |
| 从 RAG / 混合来 | 1 → 6 → 15 → 18 | llm-infra 读者 |
| 完整通读 | 1 → … → 18 | 系统掌握 |
三、目录与每篇价值点
第一部分:全景与库内核模型
- 全文引擎全景:架构叙事与引擎内核之间的一层
- 五类「搜索」反例 + Lucene/ES 分层图;与 architecture/42、vector-engine 分工。
- Lucene
文档模型:Field、docID 与正排/倒排
- indexed / stored / docValues 正交开关;纠正「一个字段只能干一件事」。
- 分析链
Analyzer:从文本到 TokenStream
- CharFilter→Tokenizer→TokenFilter;中文分词只谈接口与写代价。
- 词项词典
FST:前缀压缩与 TermsEnum
- 为何词典常驻内存;与 GIN Entry Tree 一句对照。
- Postings
与 codec:freqs、positions、skip、impacts
- 短语查询要 positions;块编码与跳跃剪枝直觉。
第二部分:打分、写入与查询执行
- BM25 与
Similarity:公式如何落到 Lucene
- Robertson 公式、norms、avgdl;与 learned ranking 的工程边界。
- IndexWriter
与 NRT:从缓冲到可打开的 Reader
- flush 产生 Segment;NRT 刷新语义与「刚写可见」。
- MergePolicy
与删除:段合并与 liveDocs
- 软删为何不立即回收空间;force merge 的代价。
- 查询执行:BooleanScorer、两阶段与
Collector
- 相交与打分路径;TopDocs 截断。
- DocValues
与 stored fields:排序聚合为何不走倒排
- 列式侧面 vs 随机取原文;聚合管线预埋。
第三部分:Elasticsearch 分布式层
- Index
· Shard · Replica:路由与 cluster state
- 主分片哈希;状态更新代价对读 architecture/42。
- refresh
· flush · translog:近实时与持久化边界
- 三者保证矩阵;
refresh_interval教学对照。
- 三者保证矩阵;
- 查询路径:协调节点上的
query + fetch
- 分片归并与 reduce;DFS 可选路径。
- 聚合与
mapping:doc values 管线与爆炸模式
- 动态 mapping 失效;为第 17 篇排障预埋。
第四部分:混合、对照与收束
- 混合检索边界:BM25
与 dense_vector
- ES/Lucene 组合接口;ANN 细节外链 vector-engine。
- OpenSearch
与 Solr:分叉与同源
- 许可/发行差异;Solr 不深拆。
- 生产排障:breaker、refresh、分片、慢查询
- 症状→机制决策树。
- 选型与阅读地图
- ES vs GIN vs CH vs 向量;回链日志选型与 RAG。
四、与相邻系列的分工
| 话题 | 本系列 | 相邻系列 |
|---|---|---|
| 搜索系统设计 / 集群故事 | 第 1/11/17 篇机制回链 | architecture/42 |
| 倒排作为索引结构之一 | 第 1–2 篇深化 | storage/29 |
| 日志后端选型 | 第 18 篇回链 | observability/08 |
| PG GIN | 第 4/18 篇对照 | postgresql-kernel/16 |
| HNSW / ANN | 第 15 篇只谈接口 | vector-engine、db-frontier/08 |
| RAG 流水线 | 第 6/15/18 篇回链 | llm-infra/17–18 |
参考
- 系列规划(PLAN.md)(写作执行文档,非发布页)
- 数据库内核索引
- 全部系列索引
- 搜索引擎架构
- 向量检索引擎
返回 数据库索引 · architecture/42 · vector-engine
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【全文检索引擎】全文引擎全景:架构叙事与 Lucene 内核之间的一层
定位 Lucene 9.x/10.x 库内核与 Elasticsearch 8.x 服务层相对 architecture/42、storage/29、向量引擎与 PG GIN 的分工;以最小索引故事建立坐标系,交代倒排索引学术谱系与 18 篇路线图。
【全文检索引擎】IndexWriter 与 NRT:从缓冲到可打开的 Reader
拆解 Lucene IndexWriter 的 RAM 缓冲、flush 出段与 DirectoryReader.open(IndexWriter) 近实时语义;说明 Searcher 刷新与「刚写入即可搜」在库层与 ES refresh 层各自保证什么。
【全文检索引擎】BM25 与 Similarity:公式如何落到 Lucene
从 Robertson & Zaragoza (2009) 的 BM25 公式出发,拆解 Lucene BM25Similarity 如何把 TF 饱和、文档长度归一与 IDF 落到 postings 与 norms;对照 TF-IDF 工程差异,并划定与学习排序的生产边界。
【全文检索引擎】混合检索边界:BM25 与 dense_vector
只谈 Elasticsearch 8.x / Lucene 上 BM25 与 kNN 的组合接口与段内共存代价,ANN 算法与专用向量引擎细节外链 vector-engine 与 db-frontier/08;指出倒排与向量同 Segment 生命周期尚未统一的开放问题。