Elasticsearch 核心原理:Posting List 倒排列表深度详解
-
- 前言
- [一、什么是 Posting List?](#一、什么是 Posting List?)
-
- [1.1 最简单定义](#1.1 最简单定义)
- [1.2 倒排索引三大部分(必须记住)](#1.2 倒排索引三大部分(必须记住))
- [二、Posting List 里面到底存什么?](#二、Posting List 里面到底存什么?)
- [三、Posting List 有什么用?](#三、Posting List 有什么用?)
-
- [3.1 基础检索](#3.1 基础检索)
- [3.2 相关性算分(TF-IDF / BM25)](#3.2 相关性算分(TF-IDF / BM25))
- [3.3 短语查询(match_phrase)](#3.3 短语查询(match_phrase))
- [3.4 高亮(Highlight)](#3.4 高亮(Highlight))
- [四、Posting List 检索流程(图解)](#四、Posting List 检索流程(图解))
- [五、Posting List 为什么这么快?(核心优化)](#五、Posting List 为什么这么快?(核心优化))
-
- [5.1 文档 ID 是**有序递增**的](#5.1 文档 ID 是有序递增的)
- [5.2 极强的压缩算法(FOR/PFOR)](#5.2 极强的压缩算法(FOR/PFOR))
- [5.3 使用 **Skip List(跳表)** 加速](#5.3 使用 Skip List(跳表) 加速)
- [5.4 联合索引(联合查询)](#5.4 联合索引(联合查询))
- 六、举个超级易懂的例子
- [七、Posting List 与 Lucene 段文件](#七、Posting List 与 Lucene 段文件)
- [八、总结(最核心 5 句话)](#八、总结(最核心 5 句话))
- 一句话终极总结
|-----------------------------|
| 🌺The Begin🌺点点关注,收藏不迷路🌺 |
前言
在 Elasticsearch / Lucene 底层,倒排索引(Inverted Index) 是实现全文检索的核心,而 Posting List(倒排列表) 就是倒排索引中真正存储数据、决定检索速度的关键结构。
如果你想真正搞懂 ES 为什么能毫秒级查询,就必须理解 Posting List。
本文用通俗语言 + 结构图 + 流程 + 底层原理 ,彻底讲清楚:
什么是 Posting List、存什么、怎么存、为什么快、如何工作。
一、什么是 Posting List?
1.1 最简单定义
Posting List = 包含某个关键词(Term)的所有文档 ID 列表
它是倒排索引的最核心部分。
结构:
关键词 → [文档ID1, 文档ID2, 文档ID3 ...]
例子:
java → [1001, 1005, 1008, 1012]
含义:包含 java 这个词的文档是 1001、1005、1008、1012。
1.2 倒排索引三大部分(必须记住)
倒排索引 =
- Term(词项):关键词(java、elasticsearch、学习)
- Term Dictionary(词词典):所有 Term 的有序集合
- Posting List(倒排列表):每个 Term 对应的文档 ID 列表
关系图:
Term Index
↓
Term Dictionary ------→ 【 Posting List 】
二、Posting List 里面到底存什么?
很多人以为只存 DocID,其实远远不止!
一个完整的 Posting List 包含 4 类信息:
- DocID(文档ID)
- TF(词频 Term Frequency):该词在文档中出现几次
- Position(词的位置):在文档第几个位置出现
- Offset(偏移量):词在文本中的起始、结束位置
完整结构:
java → [
{docID:1001, tf:2, positions:[3,7], offsets[(0,4),(8,12)]},
{docID:1005, tf:1, positions:[5], offsets[(10,14)]}
]
三、Posting List 有什么用?
3.1 基础检索
根据关键词快速找到所有包含它的文档。
3.2 相关性算分(TF-IDF / BM25)
词频 TF 用来计算文档相关度得分。
3.3 短语查询(match_phrase)
通过 Position 位置 确保词语顺序一致。
3.4 高亮(Highlight)
通过 Offset 偏移量 定位关键词位置。
四、Posting List 检索流程(图解)
输入关键词:Java
找到Term:Java
获取Posting List
DocID列表:1001,1005,1008
根据DocID获取真实文档
返回搜索结果
这就是 ES 搜索的真实底层路径。
五、Posting List 为什么这么快?(核心优化)
5.1 文档 ID 是有序递增的
- 方便快速求交、求并
- 多关键词查询极快
5.2 极强的压缩算法(FOR/PFOR)
- 大量 DocID 可以压缩到 原来的 1/10 空间
- 内存占用极小
- 读取速度极快
5.3 使用 Skip List(跳表) 加速
跳过不需要的文档 ID,加速多条件查询。
5.4 联合索引(联合查询)
多个 Posting List 快速求交集:
java AND elasticsearch
= List1 ∩ List2
六、举个超级易懂的例子
假设 3 篇文档:
- 我爱 Java
- Java 编程很有趣
- 编程改变世界
生成的 Posting List:
| Term | Posting List (DocID) |
|---|---|
| 爱 | [1] |
| Java | [1,2] |
| 编程 | [2,3] |
搜索:
Java → [1,2]
编程 → [2,3]
Java AND 编程 → [2]
这就是 Posting List 的工作方式。
七、Posting List 与 Lucene 段文件
Posting List 最终存储在这些 Lucene 文件中:
| 文件 | 内容 |
|---|---|
.doc |
DocID、词频 |
.pos |
Position 位置 |
.pay |
Offset 偏移 |
这些文件是 ES 高性能检索的基础。
八、总结(最核心 5 句话)
- Posting List = 倒排列表 = 关键词对应的文档ID列表
- 它是倒排索引的核心组成部分
- 存储:DocID、词频、位置、偏移量
- 支撑:检索、算分、短语查询、高亮
- 通过有序、压缩、跳表实现毫秒级查询
一句话终极总结
Posting List 就是 Elasticsearch 检索引擎的"心脏"。
没有它,就没有 ES 的高速全文检索。

|---------------------------|
| 🌺The End🌺点点关注,收藏不迷路🌺 |