搜索引擎架构设计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的原理的主要内容,如果未能解决你的问题,请参考以下文章