前言
由于对搜索引擎技术很感兴趣,便开始尝试开发一个搜索引擎。在参考了网上有限的资料后,加上自己钻研,最终开发出了一个小型的全网搜索引擎,底部有项目地址和搜索测试图片。
此项目的语言为PHP(语言不重要,主要的是思路、架构、和算法)。
搜索引擎的大致流程
一、网页搜集
网页搜集需要用到网络爬虫,由于互联网的连接各种各样,极不稳定,需要有一个健壮的爬虫系统来应对复杂的情况。爬取策略一般分为深度优先和广度优先两种情况,具体选择哪种视情况而定。一次HTTP请求是非常耗时的,多则1秒到几秒,因此需要使用多线程爬取(我使用的是curl_multi);同时有条件的可以配置集群爬取。
二、预处理
预处理是搜索引擎最复杂的部分,基本上大部分排名算法都是在预处理这个环节生效。那么搜索引擎在预处理这个环节,针对数据主要进行以下几步处理:
提取关键词
蜘蛛抓取到的页面与我们在浏览器中查看的源码是一样的,通常代码杂乱无章,而且其中还有很多与页面主要内容是无关的。由此,搜索引擎需要做以下几件事情:
①代码去噪。去除掉网页中所有的代码,仅剩下文本文字。
②去除非正文关键词。例如页面上的导航栏以及其它不同页面共享的公共区域的关键词。
③去除停用词。停用词是指没有具体意义的词汇,例如“的”“在”等。
当搜索引擎得到这篇网页的关键词后,会用自身的分词系统,将此文分成一个分词列表,然后储存在数据库中,并与此文的URL进行一一对应。
网页去重
互联网存在大量的重复网页内容,如果不处理就入库,会严重影响搜索体验。此步骤涉及到了海量数据的去重技术。由于网页间不能简单地用字符串比较的方式来比较是否重复,一般网页去重逻辑是,提取网页的指纹(涉及到了自然语言处理,词向量等),再进行对比去重。
比较字符串的相似度,一般的技术有“余弦相似度”、“海明距离”等。
网页除噪
在网页除噪的过程中,将网页中的标签等无用的内容去掉,并且充分利用网页代码(例如H标签、strong标签)、关键词密度、内链锚文本等方式分析出此网页中最重要的词组。
数据保存更新
当数据量一上来,所有的小问题都会成为大问题。大量数据处理过后,进行入库保存,数据库的选择和设计尤为主要。因为要兼顾海量数据的快速插入和查询。保存的数据还要考虑数据的更新问题,设计更新策略,这么多内容的爬取和更新,对服务器的性能和数量会有更高的要求。
网页重要度分析
确定一个网页的权重数值,同时结合上述的“重要信息分析”,从而确立此网页的关键词集合p中每一个关键词所具备的排名系数。
倒排索引
搜索引擎之所以能快速地查询到相对应的内容,是因为使用了索引。索引是一种数据结构。一般而言,搜索引擎使用的是倒排索引结构,即先将网页内容进行分词,将同一分词的不同文档id综合起来,以此类推。相关细节可以去详细了解。搜索引擎需要有极高的召回率,同时保证搜索的效果,所以分词器的选择和分词的策略需要细致考虑和选择。
索引又分为全量索引和增量索引,全量索引是一次性更新所有,相对比较耗时间,增量索引是每次只更新“新增加的内容”的索引,然后和旧索引合并查询。
三、查询服务
查询服务顾名思义,就是处理用户在搜索界面的查询请求。搜索引擎构建检索器,然后分四步来处理请求。
query改写
相当一部分的搜索语句都可能是表述不清、残缺的,此时如果按照原本的内容进行分词搜索,效果肯定不理想,这时就要进行query改写,使得搜索词能更准确表达搜索者的想法,从而达到一个较高的召回率。
根据查询方式与关键词进行切词。
首先先把用户搜索的关键词切分为一个关键词序列,我们暂时用q来表示,则用户搜索的关键词q被切分为q={q1,q2,q3,……,qn}。
然后再根据用户查询方式,例如是所有词连在一起,还是中间有空格等,以及根据q中不同关键词的词性,来确定所需查询词中每一个词在查询结果的展示上所占有的重要性。
内容过滤剔除
众多网页内容里面,肯定会有一些违法违规的内容存在,所以需要将相关内容剔除掉,以防被展示到前台;有时搜索者也会搜索一些敏感内容,还要将搜索query进行处理。
搜索结果排序
我们有了搜索词集合q,计算q中每个关键词相对于所属文档的重要性,进行综合性的排序算法,搜索结果就出来了。排序算法是搜索引擎的核心,影响着搜索结果的准确性,实际应用中排序的计算方法是多维度,极其复杂的。
展示搜索结果与文档摘要
当有了搜索结果后,搜索引擎就会将搜索结果展示在用户阅览的界面上以供用户使用。一般会对搜索词标红,展示效果更好。
其他
优化内容,包括使用redis等缓存工具对搜索结果进行缓存;保证速度,使用cdn等等。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。