Elasticsearch 倒排索引原理分析

📅 2026/7/19 13:49:26
Elasticsearch 倒排索引原理分析
Elasticsearch 倒排索引原理分析1 正向索引与倒排索引对比1.1 定义正向索引文档ID → 文档分词词条以文档为主体存储数据。倒排索引词条 → 文档ID集合以词条为主体全文检索核心结构。1.2 对比表格索引类型映射关系检索效率适用场景正向索引docId → terms模糊全文检索慢需遍历全部文档根据ID查询完整文档倒排索引term → docId列表全文检索极快直接定位匹配文档关键词、短语、分词检索示例文档1红色苹果文档2绿色苹果文档3红色香蕉正向索引1: [红色,苹果] 2: [绿色,苹果] 3: [红色,香蕉]倒排索引红色: [1,3] 绿色: [2] 苹果: [1,2] 香蕉: [3]2 ES倒排索引组成与底层数据结构ES底层基于Lucene单个Segment倒排索引分层结构三层核心结构均会落地磁盘持久化运行时内存加载策略不同。2.1 Term Index词条索引文件.tip数据结构FST 有限状态转换器特殊只读KV 结构key 词条前缀value 词典偏移指针存储位置永久落盘索引打开时全量加载至内存常驻作用通过前缀快速定位该前缀在词典中的偏移即词条所在词典块的起始偏移量避免全量遍历。之后通过二分查找法等算法在该词典块中查找对应的词条有可能不存在。简单案例数据红 → 词条词典偏移 1024 苹 → 词条词典偏移 2048 香 → 词条词典偏移 3072只存词条前缀词典偏移指针不存完整词条内存极低。2.2 Term Dictionary词条词典文件.tim数据结构有序词条数组前缀压缩存储存储位置全程磁盘存储mmap按需加载内容词条、文档频率、倒排表偏移指针简单案例数据红色 → docFreq2, posting_offset5001 绿色 → docFreq1, posting_offset5120 苹果 → docFreq2, posting_offset5280 香蕉 → docFreq1, posting_offset5400通过posting_offset精准找到该词条对应的倒排列表。2.3 Posting List倒排表文件.doc/.pos数据结构增量压缩数组 SkipList跳表存储位置磁盘持久化检索按需读取内容docId、词频TF、位置position简单案例数据term红色 docId[1,3] tf[1,1] term苹果 docId[1,2] tf[1,1] term绿色 docId[2] tf[1]2.4 三层结构磁盘与内存总结词条索引FST/.tip落盘常驻内存检索零磁盘IO词条词典.tim纯磁盘存储mmap按需读取倒排列表.doc/.pos纯磁盘存储按需加载链表数据2.5 配套存储结构Stored Fields.fdx/.fdt存储_source原始文档JSON用于返回原始数据DocValues.dvm/.dvd列式存储用于排序、聚合不参与检索3 ES新增数据流程流程步骤接收JSON文档text字段分词生成term写入内存缓冲区构建内存倒排索引refresh触发生成磁盘Segment落地.tip .tim .doc .fdt等索引文件后台定时合并小分段。案例写入文档PUTfruit/_doc/1{name:红色苹果}分词红色、苹果内存构建FST、词典、倒排链表刷盘生成完整索引结构原始JSON存入_source4 ES检索数据流程流程步骤分词查询语句分词得到term-词条查词条词典指针根据词条前缀在词条索引中查找词条词典指针查倒排列表指针根据词条词典指针在词条词典中查词条对应的倒排列表指针查文档ID根据倒排列表指针在倒排列表中查对应的文档ID-docId多词条链表求交集得到最终docId根据docId读取_source返回结果。案例检索关键词红色苹果GETfruit/_search{query:{match:{name:红色苹果}}}执行流程分词红色、苹果内存FST找到两个词条的词典偏移指针然后在词条词典中找到倒排列表指针。根据倒排列表指针读取倒排表得对应的文档ID红色[1,3]苹果[1,2]链表求交集 →docId1读取_source返回【红色苹果】5 总结倒排索引是ES全文检索核心正向索引用于根据ID拿完整文档三层核心结构FST词条前缀索引内存→ 有序词条词典磁盘→ 压缩倒排链表磁盘全部持久化磁盘写入构建分段索引检索通过FST快速定位、链表求交实现秒级全文检索。