很多搜索引擎都是基于倒排索引,比如luncene,solr以及elasticsearch。

英文原名Inverted index,大概因为 Invert 有颠倒的意思,就被翻译成了倒排。但是倒排这个名称很容易让人理解为从A-Z颠倒成Z-A。
一个未经处理的数据库中,一般是以文档ID作为索引,以文档内容作为记录。
而Inverted index 指的是将单词或记录作为索引,将文档ID作为记录,这样便可以方便地通过单词或记录查找到其所在的文档。

正排索引

聊倒排搜索之前先来看看正排索引,正排其实就是数据库表,他通过id和数据进行关联,如下:

数据id

数据内容

1001

苹果公司发布iPhone

1002

地球引力起源于苹果

1003

iPhone屏幕碎了

1004

我在苹果商店维修屏幕

1005

我刚刚吃了苹果

我们可以通过搜索id,来获得相应的数据,也能删除数据。你买了一本书,书的目录其实也是正排搜索

假设现在我要搜 “苹果” 俩字,那么他会对这张表格中每一行的数据做匹配,去查找一下,是否包含 “苹果” 这两个字,从第一条匹配到最后一条,如果一张表中数据量不多,几万,十几万,那么问题不大,但是一旦数据量有上百万,上千万,那么全表扫描这种的搜索性能就会有影响。

其次,这个时候我想搜索 “苹果iPhone”,那么我们无法把这词汇拆开再到数据库去搜索。

  • 优点:使用起来方便,原理也简单,比较入门
  • 缺点:检索效率低下,适合简单场景使用,比如传统项目,数据量较小的项目。不支持分词搜索。

 

倒排索引

与正排是反着来的,他会把文档内容进行分词,比如苹果公司发布iPhone是一个文档数据,当我们把他存入到搜索引擎中去的时候,会有一个文档id,这个文档id就类似于数据库主键。但是这文档存储的时候和数据库不一样,他会进行一个分词,参照上面的表格,分词后的结果如下:

数据id

文档数据

分词结果

1001

苹果公司发布iPhone

苹果,公司,发布,iPhone

1002

地球引力起源于苹果

地球,引力,起源,于,苹果

1003

iPhone屏幕碎了

iPhone,屏幕,碎了

1004

我在苹果商店维修屏幕

我,在,苹果,商店,维修,屏幕

1005

我刚刚吃了苹果

我,刚刚,吃了,苹果

每一个词汇都会和文档id关联起来,可以根据词汇来找到所有出现的id列表,如下:

词汇

文档ids

苹果

1001,1002,1004,1005

iPhone

1001,1003

公司

1001

发布

地球1001

引力

1001

起源

1001


1001

屏幕

1003,1004

碎了

1003


1004,1005


1004

商店

1004

维修

1004

刚刚

1005

吃了

1005

假设现在我要搜索iPhone,如果是数据库搜索,假设有1亿条数据,那么会匹配1亿次,全表扫描。最后再把数据返回出来。

如果是搜索引擎,那么有可能第一次就把所有文档数据给查出来,当然也有可能是第N次,当然他肯定要比数据库的搜索效率更高。如图中位置,他会直接把1001,1003两个文档返回。

可能会有同学会问,数据库和搜索引擎都是1000万数据,搜索的词汇在搜索引擎中正好是第1000万条,那么会不会慢,其实这个肯定会比数据库更快,数据库要匹配是一个文本中的内容和关键词匹配,而搜索引擎是直接把关键字做匹配,效率肯定后者更快。

  • 有点:搜索更快,耗时短,用户体验高,精装度也高
  • 缺点:维护成本高,索引新建后要修改,必须先删除,前期需要很好地规划