中文搜索引擎原理分析与实现(1)基本理论

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26822029/article/details/86649449

说起搜索引擎,我们肯定会说百度!谷歌!当然,这些人人皆知的检索系统当然属于搜索引擎,不过在app里,在论坛上都会有一个搜索框,大部分的搜索框的背后都有一个或大或小的搜索引擎。搜索引擎本质上就是一个检索系统,为用户提供信息检索服务的。那么搜索引擎到底是如何实现的呢?

起初,我有一个懵懂的想法:搜索引擎就是在数据库里查找数据是否满足我们输入的查询内容吧!比如,我输入“西安交通大学”,那么就相当于在数据库中查询类似“SELECT * FROM table_name WHERE content_name LIKE %西安交通大学%”这样的语句,然后对返回的内容进行排序,再输出就好了。对于这样的回答,我只能说Naive。在数据库存储的数据量比较小的情况下,这样的做法的确可行,我自己尝试过,当数据库中的数据在1万条的时候,能在几十毫秒之内返回这样的查询结果。然而在实际的应用环境下,数据库中的数据动辄成百万千万,这样的查询语句根本吃不消。除此之外,这样的查询仅仅是字符的匹配,用户体验极差。

所以搜索引擎的工作原理是什么呢?答案就是

为了提高查询的响应速度,我们不会在执行查询的时候才到数据库中搜索,而是提前对当前的数据建立索引。这个感觉就像查字典,字典对其中的内容按照某种规定的方法编排(一般是按照字母的顺序),那么在查询字典的时候我们没必要从第一页开始往后查,直接查字典的索引就好了。

因此,可以说搜索引擎的核心模块是倒排索引的建立,下面介绍什么是倒排索引。

1 什么是倒排索引

如果有以下两个文档,其中的内容分别是:

想要对其创建索引,第一步是进行分词——将完整的句子分为一个一个的词组。

可以看到,上面的分词结果中有一些虚词和标点符号我们并不需要,这样的需要删去的词我们称为停用词,因此第二步叫做去停用词。

第三步就是建立倒排索引。倒排索引是和正向索引相对应的,像第二步的结果这样就是正向索引——通过文档(Doc)索引其中的内容(大白话就是在查询的时候一个一个访问文档,找到匹配项)。因此倒排索引就是利用文档中的关键字来索引文档,实现检索。下面的是最简单的倒排索引,索引的内容只有关键词属于的文档id。

下面的索引带有在文档中出现的次数。

在建立完成这样的倒排索引之后,就可以进行查询了。比如我的查询语句是“深圳是经济特区吗?”,首先对这一查询语句进行分词“深圳 / 经济 / 特区”,然后分别使用这三个关键词在倒排索引中进行查询。最终的查询结果如下图所示:因为Doc2命中了全部的三个关键词,因此其得分最高,而Doc1只命中了一个关键词,在bool查询下,也可以将其作为查询结果返回。最终返回Doc2, Doc1作为查询结果。

以上便是利用倒排索引实现搜索引擎的基本方法。下面具体分析一下倒排索引的实现。

2 倒排索引的实现

倒排索引的理论很简单,难点在于如何建立这样的索引。从形式上来看,一个单词的索引就像是一个链表一样。

每个关键词可以通过一个指针指向其倒排列表。但是这样的设计存在一个致命的问题:当文档比较少时,的确可以这样做,将整个倒排索引保存在内存中,可是如果有上百万条文档呢?恐怕内存中装不下吧。还有另外一个问题:在查询的时候,我如何快速的定位到我想要查询的关键词呢?如果倒排索引中有上万条关键词,难道要一个个遍历直到定位到我查询的关键词吗?Of course NOT!

鉴于以上两个问题,常用的可行方案是:在二级存储上使用关键词的树形结构或者哈希映射实现关键词的词典。在实现词典时,为了能够快速的获取到对应着单词的倒排表,通常都会使用哈希表、树等数据结构。常用的树形数据机构有保存着各个单词顺序的二叉查找树和字典树等等。

使用二叉查找树实现词典时,要先将数据对(的列表)按照单词的词典顺序进行排列,然后存储到存储器中。数据对是由单词和对应着该单词的倒排索引列表的引用信息构成的。若是在二级存储上实现词典时,也要先将数据对按照单词的词典顺序排列,然后一个接一个地存储到存储器上。但是如果知识单纯的一个接一个地存储,就无法直到各个数据对应该在哪里结束了,因此在此之上还要维护一个列表,用于存储从开头算起每个数据对的偏移量。对应的结构如下图所示,在进行检索时,可以对该偏移量的列表进行二分查找。

猜你喜欢

转载自blog.csdn.net/qq_26822029/article/details/86649449