🌺The Begin🌺点点关注,收藏不迷路🌺

前言

倒排索引(Inverted Index) 是 Lucene 和 Elasticsearch 的灵魂,是全文检索能做到秒级响应的核心数据结构。

几乎所有搜索引擎、大数据检索组件,底层都依赖倒排索引。但绝大多数开发者只知其名,不知其实现

本文从原理 → 结构 → 构建流程 → 代码实现 → 检索流程,用最通俗的方式带你从零实现 Lucene 倒排索引,彻底搞懂 ES 为什么快。


一、什么是倒排索引?

1.1 正排索引(数据库索引)

文档ID → 单词列表
需要遍历所有文档才能查关键词,

1.2 倒排索引(搜索引擎索引)

单词 → 文档ID列表(倒排表)
通过关键词直接定位文档,极快

1.3 核心结构

  • Term(词项):分词后的最小单元(关键词)
  • Posting List(倒排表):包含这个词的文档ID集合
  • Term Dictionary(词词典):Term 的排序集合
  • Term Index(词项索引):对 Term Dictionary 的索引,加速查找

二、倒排索引完整结构

Term Index   (单词索引)
   ↓
Term Dictionary (单词词典:排序、二分查找)
   ↓
Posting List    (倒排表:文档ID列表、频率、位置)

2.1 示例

文档:
1:我爱Java
2:Java编程
3:编程学习

倒排索引:

Java   → [1, 2]
编程   → [2, 3]
我爱   → [1]
学习   → [3]

三、Lucene 倒排索引构建完整流程(底层真实流程)

3.1 构建步骤(图文版)

  1. 文档采集:读取原始文档内容
  2. 分词(Analyzer):将文本切分成 Term
  3. 词项处理:转小写、去停用词、归一化
  4. 建立映射:Term → 文档ID、词频、位置
  5. 写入内存缓冲区
  6. 生成段文件(Segment)
  7. 持久化到磁盘

3.2 构建流程图

原始文档

分词器Analyzer

生成Term词项

建立Term→DocID映射

写入内存缓冲区

生成倒排索引段Segment

写入磁盘

可检索


四、Lucene 倒排索引检索流程

4.1 查询流程

  1. 输入查询关键词
  2. 分词生成 Term
  3. 通过 Term Index 快速定位
  4. Term Dictionary 二分查找
  5. 获取 Posting List
  6. 取文档ID → 返回结果

4.2 为什么这么快?

  • Term Index 放在内存,O(1) 定位
  • Term Dictionary 有序,二分查找 O(logN)
  • Posting List 压缩存储,IO 极小

五、手写实现:极简版倒排索引(Java 代码)

下面用 100 行 Java 代码 实现一个迷你 Lucene 倒排索引,包含:

  • 分词
  • 索引构建
  • 关键词检索

5.1 代码实现

import java.util.*;

/**
 * 极简倒排索引实现
 */
public class InvertedIndex {
    // 倒排索引核心结构:Term -> 文档ID集合
    private final Map<String, Set<Integer>> index = new HashMap<>();

    // 新增文档,构建索引
    public void addDocument(int docId, String content) {
        // 1. 分词(简单按空格分词)
        String[] terms = content.split(" ");
        
        for (String term : terms) {
            term = term.toLowerCase(); // 统一小写
            // 2. 创建倒排项
            index.computeIfAbsent(term, k -> new HashSet<>()).add(docId);
        }
    }

    // 关键词检索
    public Set<Integer> search(String keyword) {
        return index.getOrDefault(keyword.toLowerCase(), Collections.emptySet());
    }

    // 测试
    public static void main(String[] args) {
        InvertedIndex index = new InvertedIndex();
        
        // 添加文档
        index.addDocument(1, "I love Java");
        index.addDocument(2, "Java programming");
        index.addDocument(3, "programming study");

        // 查询
        System.out.println(index.search("Java"));      // [1,2]
        System.out.println(index.search("programming"));// [2,3]
    }
}

5.2 运行结果

[1, 2]
[2, 3]

这就是 Lucene 倒排索引最核心的原理!


六、Lucene 倒排索引真实底层存储格式

Lucene 会把倒排索引存储为 .tim、.tip、.doc、.pos 等文件:

文件 作用
.tip Term Index(内存索引)
.tim Term Dictionary(词词典)
.doc Posting List(文档ID列表)
.pos 词项位置
.pay 有效载荷

七、Lucene 倒排索引的核心优化(ES 高性能的秘密)

7.1 Term Index (基于 FST 结构)

  • 内存占用极小
  • 极高检索效率
  • 支持前缀匹配

7.2 Posting List 压缩算法

  • FOR 压缩
  • PFOR 压缩
  • 空间减少 80%+

7.3 有序倒排表

  • 快速求交、合并、求并
  • 加速多条件查询

7.4 段(Segment)不可变

  • 无锁
  • 高并发
  • 检索极快

八、倒排索引核心总结(面试必背)

  1. 倒排索引 = Term + Term Dictionary + Posting List
  2. Lucene 使用 FST 构建 Term Index
  3. Posting List 存储文档ID、词频、位置
  4. 查询 = 词项查找 + 倒排表取文档
  5. 段文件不可变,高性能基石

九、本文总结

倒排索引是搜索引擎的核心,Lucene 作为 ES 底层,通过:

  • 分词
  • 倒排映射
  • FST 索引
  • 压缩存储
  • 段不可变

实现了海量数据下的毫秒级检索

理解倒排索引,你就真正理解了 Elasticsearch 为什么是世界上最快的搜索引擎。


在这里插入图片描述


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

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐