搜索引擎架构设计lucene的原理

Posted 也输思雪计算机之路

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搜索引擎架构设计lucene的原理相关的知识,希望对你有一定的参考价值。

目录

  • 缘起

  • 倒排索引

  • Lucene流程

  • 总结

缘起

周末吃饭,听到旁边有人说,“这百度厉害,一搜索就出来了”。正想后续写什么系列呢,所以有感而发,打算开一个新系列“搜索引擎架构设计”(喂,其他系列都还没更新呢)。

当出现大量搜索时,乃至全文搜索时,项目架构就得考虑“外置搜索架构”了,也即是“搜索引擎架构”,一般都会是基于现有的框架开发或者自研发。在全文搜索行业,目前属elasticsearch和solr为热,那我们今天就来探一下这两个的底层。

es和solr都是基于Lucene开发的框架,对Lucene进行了封装再处理,让使用者更加方便灵活使用,那要学会es和solr的底层原理,那我们就得知道Lucene的原理。

倒排索引

    我们要找某一个文章中,某个单词出现的次数和地方,那么一般正常的是:循环每一篇文章,判断每个词是否为要找的,是则记录下位置和更新次数,也即是以“文档号”为记录,是以“记录”去找的“属性”(或者叫字段),这就是“正排索引”,这也是常见的数据库的搜索方式(如mysql)。但当这记录很大时,而且记录很多时,这样查找会相当的耗费时间,那这时怎么办?答:倒排索引

倒排索引,是以“属性”来确定“记录”,也即是用“属性”来查找所有包含该“属性”的“记录”,这就是倒排索引。将非结构化的数据(没有规则),从中按照某一规则提取某些部分,来重新组织,后续则可以通过这“有规则的部分数据”来渐渐缩小范围,提高查找效率,其实这也是所有“索引”出来的背景。(可以细细的想一下)。

那么倒排索引也是一样,也得在创建数据时做点文章,想一下,比如录入每个文档时,都将文档的每个单词记录下来,记录单词在本文档中出现的位置和频次(先判断该记录是否已存在,没有则新建,有则更新),下一个文档录入时,也是如此。比如,文档A内容是“my name is Opjesus” ,文档B内容是“my name is Mike”.则处理之后得到结果如下:


分词 所在文档 频次
my A,B 2

name

A,B

2
 is
 A,B 2
Opjesus A 1
Mike B

1

Lucene流程

我们接着上面表继续分析,想要的会是这种结果。那怎么做呢?第一步是录入文档,将文档的每个单词记录下来,记录单词在本文档中出现的位置和频次(先判断该记录是否已存在,没有则新建,有则更新)”,那问题来了,第一步是怎么判定“单词”呢?怎么判定规则是什么?

      所以,第一步是“分词”,分词的处理,Lucene有分词器来处理,那有什么规则吗?是所有词都存吗?

      当然有规则,不会存所有,存有意义的词,比如标点符号,副词,连词之类的就不用存了,例如上表中的"is"就不用存。

       好了,这个词倒是分了,那还可以优化什么吗?也就是减少范围(缩小边界),英语中一个单词有很多种形式,比如复数形式,单数形式,过去式,现在时等等,那其实这些我们可以完全只存一个啊,那就是原始的。这就是第二步了,这里Lucene中的工具是“语言处理程序”。

        到这里了,也缩小很大范围了,那上面说的是英文,可有其他语言的咋办?这个就是需要组件来扩展了,比如有中文分词器,韩文分词器等等。

        到这里的话,那么该缩小的范围都缩小了,那就剩下存储了,上面表中的“所在文档”,怎么存?一个分词对应着很多个文档呢,还要存放所在位置之类的,答:链表。这就是第三步,倒排表。比如:

       my 2 ->A 0 ->B 0

总结

Lucene的基本原理步骤为:分词器,语言处理程序,倒排表。其实最主要的就是“倒排索引”这种思想,所以大家把这种思想可以学习下,对后续自研发设计搜索很有帮助。另外这种思想我在前面文章其实提到过。

点个赞吧。

关于我


以上是关于搜索引擎架构设计lucene的原理的主要内容,如果未能解决你的问题,请参考以下文章

ES: 架构及原理

突击Java面试-分布式搜索引擎的架构原理

es 的分布式架构原理

es分布式架构原理

ES 的分布式架构原理能说一下么?

深度解析 Lucene 轻量级全文索引实现原理