ElasticSearch倒排索引原理
文章目录
- 从正向索引说起
- 正向索引的查询过程
- 倒排索引
- 倒排索引的查询过程
- 倒排索引的构建过程
- 1. 文档分析阶段
- 2. 倒排索引构建
- 3. _source存储
- ElasticSearch搜索过程详解
- 核心原理
- 两大核心阶段:索引构建 & 文档搜索
- 为什么倒排索引如此高效?
- 总结
从正向索引说起
在理解倒排索引之前,我们先来看看什么是正向索引。正向索引是我们最直观、最熟悉的数据组织方式,它建立的是"文档ID → 文档内容"的映射关系。
正向索引的查询过程
当用户搜索"ElasticSearch"时,正向索引的查询过程是:
1. 从doc1开始逐个检查文档内容doc1: "ElasticSearch是..." 包含"ElasticSearch"
2. 检查doc2: "Lucene是ElasticSearch..." 包含"ElasticSearch"
3. 检查doc3: "搜索引擎广泛..." 不包含"ElasticSearch"
4. 检查doc4: "分布式系统..." 不包含"ElasticSearch"
5. 检查doc5: "ElasticSearch基于..." 包含"ElasticSearch"查询结果: [doc1, doc2, doc5]
倒排索引
倒排索引反其道而行之,建立的是"词条 → 文档列表"的映射关系。
倒排索引的查询过程
当用户搜索"ElasticSearch"时:
1. 查询词条标准化: "ElasticSearch" → "elasticsearch"
2. 直接在倒排索引中查找: "elasticsearch" → [(doc1, [0], 1), (doc2, [2], 1), (doc5, [0], 1)]
3. 提取文档ID: [doc1, doc2, doc5]
4. 从_source中获取完整文档内容返回查询时间复杂度: O(1) 或接近 O(1)
倒排索引的构建过程
1. 文档分析阶段
当新文档写入ES时,首先要经过文档分析阶段。这个阶段是构建倒排索引的起点。
分词处理
ES使用分析器(Analyzer)对文档进行处理,分析器包含三个核心组件:
- Character Filter:字符过滤,如去除HTML标签
- Tokenizer:分词器,将文本切分成词条
- Token Filter:词条过滤,如转小写、去除停用词
例如,对于文档 {"title": "The Quick Brown Fox"}
:
原始文本: "The Quick Brown Fox"
经过分析器: ["the", "quick", "brown", "fox"]
2. 倒排索引构建
经过分析后的词条会被用来构建倒排索引:
词条 | 文档列表(包含文档ID、位置、频率)
--------|--------------------------------
the | [(doc1, [0], 1)]
quick | [(doc1, [1], 1)]
brown | [(doc1, [2], 1)]
fox | [(doc1, [3], 1)]
3. _source存储
重要的是,ES会将原始的JSON文档完整保存在一个名为 _source
的字段中。这个设计非常关键:
- 倒排索引用于快速检索
- _source用于返回完整的原始文档内容
ElasticSearch搜索过程详解
核心原理
用户写入文档时分词构建倒排索引,搜索时对查询语句同样分词,然后通过倒排列表快速找到匹配的文档ID,最后从原始存储中取出文档返回结果。
两大核心阶段:索引构建 & 文档搜索
阶段 | 关键步骤 | 核心作用 |
---|---|---|
阶段1:索引构建(文档写入) | ||
接收文档 | 接收JSON文档,如 {"title": "The Quick Brown Fox", "content": "..."} | 原始数据输入 |
文本分析(Analysis) | 使用分析器进行分词、小写转换等处理 → ["the", "quick", "brown", "fox"] | 文本标准化处理 |
构建倒排索引 | 记录每个词出现在哪些文档(Doc ID)、出现位置、词频统计 | 建立快速检索的核心数据结构 |
存储_source | 原始JSON文档完整保存在_source字段中,用于结果返回 | 保证数据完整性 |
索引阶段完成 | 建立了"词条 → 文档ID"的映射关系 | 为快速搜索打下基础 |
阶段2:搜索查询(文档检索) | ||
---|---|---|
用户输入查询 | 用户输入搜索语句,如 "quick brown" 或复杂的DSL查询 | 搜索需求输入 |
查询分析 | 使用相同的分析器对查询进行分词 → ["quick", "brown"] | 查询标准化(保证一致性) |
查询倒排列表 | 分别查找 quick 和 brown 出现在哪些文档中 | 利用倒排索引快速定位 |
计算文档交集 | 找出同时包含多个查询词的文档,进行布尔运算 | 精确匹配文档筛选 |
相关性排序 | 使用BM25等算法计算文档与查询的相关性得分 | 结果质量优化 |
获取原始文档 | 根据文档ID从_source中读取完整的原始内容 | 完整信息返回 |
返回搜索结果 | 包含文档内容、相关性得分、高亮显示等信息 | 用户体验优化 |
搜索阶段完成 | 毫秒级返回精准的搜索结果 | 高效搜索体验 |
为什么倒排索引如此高效?
传统数据库的模糊查询
SELECT * FROM documents WHERE content LIKE '%elasticsearch%';
这种方式需要全表扫描,时间复杂度为O(n)。
ES倒排索引查询
elasticsearch -> [doc1, doc5, doc12, doc89, ...]
直接通过词条定位文档,时间复杂度接近O(1)。
总结
ES通过倒排索引先找到文档ID,再获取文档内容
Elasticsearch通过"写时建索引、读时查索引"的核心机制,利用倒排索引这一精妙数据结构实现毫秒级全文检索。其中,文档分析确保了查询的一致性,倒排索引提供了检索的高效性,而_source存储保证了数据的完整性。三者协同工作,共同构建了现代搜索引擎的技术基石。