1. 项目介绍
1.1项目简介
boost-C++LIBRARIES是C++的第三方库,boost库是一个非常强大剽悍的库。在C++未来的发展趋势中,我认为boost可能会加入到C++的标准库中,但是boost网站没有搜索文档的这个功能,因此做个项目。这个项目是一个基本boost文档的搜索引擎,当用户输入一个查询词时,把这个关键词的相关文档网页查找出来,已达到搜索文档的目的。
点击上面的Boost SOSO就可以进入搜索引擎的界面。
GitHub源码
1.2 模板
在实现搜索引擎之前,以百度为例,展示出来的界面,应有标题、摘要、URL
2. 项目的实现
2.1 项目的组织结构
项目的实现结构总共分为三个模块:
数据处理模块:对待搜索的网页进行预处理对html进行去标签处理。
索引模块:根据数据处理模块的结果,构造正排索引和倒排索引。
搜索模块:根据输入的查询词对索引进行查找文档id,通过文档id找出文档,即就是从倒排索引,找到倒排索引。
2.2 数据处理模块
数据处理模块,是对源html文档,进行去标签处理,分析出标题、正文、URL。
对存储源html文档的目录进行遍历,枚举出所有的html文档路径,然后保存在vector
中。
遍历vector
,依次处理每个枚举出的文档,对文档进行分析,分析出标题/正文/url,并且去标签。
把分析的结果按照一行的形式写入到输出文件raw_inout
中。
主要实现是对文档的解析,如第一个about.html
文档。对其解析:
- 首先是标题:标题的形式是
<title>标题</title>
,于是找< title>/标题</ title>之间的字符串就是标题。 - 然后是正文:除标签之外的都是正文,即一对<>之外的字符串都是正文,于是如果是<就是标签的开始,如果是>就是标题的结束,中间的字符串舍弃
- 接下来就是URL:我是以boost1_70版本的,所以以
https://www.boost.org/doc/libs/1_70_0/libs/filesystem/doc/index.htm
为例可以发现,doc后面就是路径+html文档。于是string prefix = "https://www.boost.org/doc/libs/1_70_0/doc/"
+ 文档名。
最后分析完成之后,需要把分析的结果按照一行的形式写入到输出文件中,为了区分标题,正文,URL,于是在其中间加上’\3’。
string line = info.title + "\3" + info.url + "\3" + info.content + "\n"
2.3 索引模块
这是最难的一个模块,首先介绍一下分词正排索引和倒排索引。
2.3.1 正排索引
于是正排所以就是为了给定编号,获取相应文档。
2.3.2 倒排索引
反之倒排索引就是根据关键词找文档编号。如:
对于上面关键词,当收到后,就会找到对应的文档编号。
2.3.3 构建索引
现在来到比较难做的构建索引。
1、正排索引的构建
- 按行读取每个文档。
- 对这行内容进行切分,依据为’\3’ 对读到的每一行构造DocInfo对象,插入到vector,即就是正排索引。
struct DocInfo
{
uint64_t id;//文档id,以vector的下标为文档id
std::string title;//文档标题
std::string content;//文档正文
std::string url;//文档URL
};
2、倒排索引的构建
- 先对当前的docinfo进行分词,即就是对正文和标题分词
- 对分词结果进行进行词频统计,以结构体Weight记录
- 遍历分词结果,在倒排索引中查找,如果存在,找到对应的值(vector),构建新的Weight对象插入到vector中,如果不存在就构建新的键值对。
struct Weight
{
uint64_t doc_id;//文档id
int weight;//权重,为排序做准备,当前用词频计算权重
std::string key;//关键词
};
最后没个词都有一个vector,这个vector里面存的就是,它在每个文档的权重,还有文档的编号。也就是这个词在这个文档当中出现了几次,当时权重的公式以一个粗暴的方式计算
#define EQ 20 /*权重公式(equal) : 标题词是正文词的20倍*/
weight.weight = EQ * word_pair.second.title_cnt + word_pair.second.content_cnt;
3、总揽
2.4 搜索模块
搜索模块相对简单,就四大部分
- 对输入的查询词进行分词
- 对分词结果查找倒排索引,找到相关文档id
- 根据权重排序
- 以jsoncpp格式构造结果,最后整体返回为一个字符串。
2.5 总览
3. 发布
目前已经部署到个人服务器上,由于限制带宽,所以第一次进入可能会有一些慢。
Boost SOSO