知识卡片

全文搜索引擎的倒排索引原理与正排索引的本质区别

结构图卡

内容

[[NoSQL的本质定位是针对关系数据库四大缺陷的补充方案]]里全文搜索引擎(以Elasticsearch为代表)针对的是”关系数据库全文搜索弱”这个缺陷,根源在于关系数据库的索引机制天生不适合全文搜索:一方面全文搜索的条件可以任意组合,如果每种组合都要靠索引支撑,索引数量会爆炸式增长;另一方面全文搜索本质是模糊匹配,索引本身解决不了这个问题,只能退化成like整表扫描,性能极低。以一个”程序员发布信息、用户来搜索程序员”的婚恋网站为例:不同用户的搜索条件千差万别(有人搜”性别+PHP+上海”,有人搜”性别+鹅厂+旅游”,有人搜”性别+猫厂+北京+Java+技术专家”,有人只搜”性别+美丽+美女”),这些条件横跨姓名/地点/单位/爱好/语言/自我介绍等多个字段,且经常是模糊匹配,如果靠传统索引支撑,几乎要给每个字段都建索引还未必够用。全文搜索引擎的核心解法是倒排索引(Inverted Index):和关系数据库习惯的”正排索引”(建立文档到单词的索引,即知道文档ID去查它包含哪些内容,适合按文档名称查内容)方向相反,倒排索引建立的是单词到文档的索引——记录每个单词分别出现在哪些文档里,因此特别适合”按关键词找文档”这种全文搜索的核心诉求(比如想找所有提到”设计”这个词的文章,直接查”设计”这个单词对应的文档ID列表即可,不需要逐篇扫描)。由于全文搜索引擎的索引对象是”单词和文档”,和关系数据库”键和行”这套术语体系不是一回事,要让全文搜索引擎支持关系型数据的全文检索,需要先把关系型数据转换成JSON文档再喂给搜索引擎建索引;以Elasticsearch为例,它默认会给JSON文档里的每个字段都建立专属的倒排索引,并且能在同一次查询里同时利用多个字段的倒排索引,从而在复杂组合条件下依然能保持很高的检索速度。

结构图

flowchart LR
  A["正排索引:文档→单词"]
  A --> A1["按文档名称查内容<br/>如点击标题展示全文"]
  B["倒排索引:单词→文档"]
  B --> B1["按关键词找包含它的文档<br/>如搜'设计'返回所有含该词的文章ID"]
  B --> B2["全文搜索的核心诉求正是<br/>'按关键词找文档',天然匹配倒排索引"]
  C["关系数据库索引的局限"]
  C --> C1["条件任意组合→索引数量爆炸"]
  C --> C2["模糊匹配→只能退化成like整表扫描"]
  C1 --> D["解法:关系数据转JSON文档<br/>喂给搜索引擎按字段建倒排索引<br/>(如Elasticsearch)"]
  C2 --> D
  B2 --> D

参考来源

- 位置:《从零开始学架构》第16讲《高性能NoSQL》"全文搜索引擎"(源文件:_epub-src/OEBPS/text00001.html) - 结论依据:原文说明全文搜索的两个问题"全文搜索的条件可以随意排列组合,如果通过索引来满足,则索引的数量会非常多……全文搜索的模糊匹配方式,索引无法满足,只能用 like 查询",并解释倒排索引"基本原理是建立单词到文档的索引……'正排索引'的基本原理是建立文档到单词的索引",以及"在 Elasticsearch 中,每个字段的所有数据都是默认被索引的……它能在相同的查询中使用所有倒排索引,并以惊人的速度返回结果",直接支撑本卡片结论与结构图。 - 原始内容:全文搜索的条件可以随意排列组合,如果通过索引来满足,则索引的数量会非常多……全文搜索引擎的技术原理被称为"倒排索引"……其基本原理是建立单词到文档的索引……"正排索引"的基本原理是建立文档到单词的索引。