搜索引擎项目
功能
- 实现了一个基于boost 文档的搜索引擎,用户输入查询词,能够把和这个词相关的文档的网页都查找出来,类似于百度搜索。
模块化介绍
-
分为三大模块
-
数据处理模块:对待搜索的网页进行预处理
-
索引模块:根据数据处理模块的结果,构造出正排索引和倒排索引。
-
搜索模块:根据用户输入的查询词,对索引进行查找,最终找出那些文档和这个词有关系。
一:数据处理模块详解
- 实现
- 输入:boost 文档中对应的html 文件
- 输出:去掉标签之后的结果
- 拿到boost 文档后,我们发现这些文档中,包含了 html 文件、图片文件还有一些目录。而我们要做的是保留 html 文档,去掉其他的所有文件。
- 这个过程中我用到了boost库中filesystem 库(文件系统操作库),将我的所有html 文档路径存到一个vector 中。
- 这个过程中我用到了boost库中filesystem 库(文件系统操作库),将我的所有html 文档路径存到一个vector 中。
- 拿到这些文档路径后,打开文件,读取文件内容,对html 文档进行解析,分别解析出标题、正文、URL。
- 标题:< title >标题< /title>
- 正文:除了标签之外的东西,都是正文。
- URL:boost 官网url 前面部分+我的文件路径的一部分即可。
- 标题:< title >标题< /title>
- 将解析好的标题、正文、URL 输出到一个行文本文件中,这个文件每一行对应一个html 文档,中间使用特殊字符当做分隔符进行分割。分隔符必须是正文标题url 不会出现的字符,于是我选择了ASCII 中的已经被弃用的字符 ‘\3’ 。
至此,数据处理模块结束
二:索引模块详解
- 实现:根据数据处理的结果,构建正排索引和倒排索引。
- 正排索引:给定编号,就能获取到文档内容
- 倒排索引:给定一个词,就能获取到这个词和那些文档有关联
- 构造一个结构体 DocInfo,这个结构体中有 文档编号、文档的标题、正文、URL。
- 构造一个机构体 Weight,这个结构体中有 给定词、文档编号、词的权重。
- 构建正排索引的容器是vector,vector里面是 DocInfo 结构体,使用下标作为文档的i编号id。
- 构建倒排索引的容器是 unordered_map,其中 K 是给定词(string),V是vector 中套一个Weight结构体;因为一个词可能会出现在多个文档中。
- 拿到行文本中的每一行,进行切分,放到我正排索引的容器 vector 中。在切分的字符串时,用到boost库中split 函数。
- 将每一行切分出来的标题和正文进行分词,(使用 jieba 分词第三方库),将分词结果存储在 vector< string> 中。
- 对DocInfo 中的标题和正文进行词频统计,当前词在标题中出现几次,在正文中出现几次,定义一个 unordered_map ,K 是给定词,V 是WordCnt 结构体,结构体里面有标题的词频和正文的词频。
- 这里会有一个问题,就是查询的过程中是不区分大小写的,因此我们在处理的时候将所有的词都化作小写来处理。我们使用boost 库中的 to_lower 函数进行大写转小写。
- 将分词结果放到我构建的倒排索引的容器 unordered_map 中。
- 如果该词在倒排索引中不存在,就构建新的键值对。
- 如果该词在倒排索引中存在,就找到对应的 vector ,构建新的 Weight 对象插入到 vector 中。其中标题词频和正文词频占不同的权重。
搜索模块详解介绍
- 实现:根据用户输入的查询词,对索引进行查找,最终找出那些文档和这个词有关。
- 对查询词进行分词
- 针对每个分词结果查找倒排索引,找出那些文档具有相关性。
- 这块有一个问题:如果不同的分词对应相同的文档id 的话,需要去重,并且进行权重合并。
- 我们只需要在排序的时候,首先根据 id 进行排序,把相邻的相同 id 的权重合并,并且只保留一个 id 。再以权重进行排序即可。
- 按照词出现的频率进行降序排序
- 构建返回结果:根据得到的ID 列表,查找正排索引得到搜索结果。
- 在得到搜索结果后,使用 jsoncpp 这个库,将结果转换成 json 串发送给浏览器客户端,当然不会把所有的正文都发送过去,只是将出现该词的那一段发过去。
至此,搜索引擎所有的功能已完成,现在需要搭载在HTTP 服务器上,进行服务端和客户端的交互。
HTTP 模块
- 这个模块我暂时调用的是第三方库 htttplib 库,直接模拟 HTTP 服务器,搭载我要查询的内容发给自己的服务器,然后我自己的服务器又返回 JSON 串数据在浏览器客户端。
- emmmmmm,前端的知识还没有学,所以没有很丑很丑的页面。后期会补上的。
源码地址:https://github.com/zhangyi-13572252156/search_engine
整个项目到这里就完了,后期还会更新。