一、该搜索引擎是对boost源码进行搜索,针对boost文档进行简单的搜索功能
写这个搜索引擎的原因:实现一个基于boost文档的搜索,数量太大时,可能不好实现,数量较小时,可以正常实现,并且boost库中没有一个合适的搜索功能。使用boost时,发现查一个东西不好查,所以想要自己实现一个服务器
2、项目应包含的模块
http服务器
CGI程序:(搜索客户端)
搜索服务器:
索引模块:
3、介绍一个项目时:
(1)首先应该介绍项目背景(为什么要实现这个项目)
(2)项目解决了什么问题(boost库不好用)
(3)为了解决这个问题是怎么做的,模块和模块之间的关系
4、搜索流程:
(1)访问主页:浏览器访问http服务器获取到主页的html
(2)进行搜索:
A)浏览器发送http一个get请求,【get和post的区别:get请求是通过,query_string传递请求;post请求是通过http协议中的body传递参数】【post请求中,body数据的格式是什么?具体的格式通过content_length来进行约束】,包含一个query参数把查询此传递给HTTP服务器
B)HTTP服务器收到请求之后,解析出其中的query参数,通过CGI程序包装成TCP请求,发送给搜索服务器(搜索服务器是一个TCP的服务器);
C)搜索服务器收到请求之后进行检索,得到响应数据
包含的要素:标题,描述,show_url,jump_url
返回给CGI程序
D)CGI程序拿到响应数据后,根据响应数据,包装成html,返回给浏览器
(3)搜索的具体流程:
A)搜索服务器对此查询进行分词,查询词可能为一句话
使用第三方库:cppjieba 结巴分词(开源的库)
B)针对每个分词结果,进行触发
核心是通过倒排索引进行实现
倒排索引:
C)、针对触发的文档结果,进行排序
排序的依据主要词出现的位置和频率
D)、根据排序后的id列表,从正排索引中获取到对应的数据,然后包装成TCP响应
boost库一点都不强大,就几个容器、几个算法
使用的第三方库:
gflags:谷歌开源的管理命令行参数配置的库
glog:谷歌开源的日志库
protobuf:谷歌开源的序列化库【序列化把一个对象(结构体,类)转化为字符串;反序列化就是将字符串转化为结构体】【(1)可以将结构体转化为char*,把结构体对应的类型理解为字符数组(局限性很大);(2)用特定的限定符分割开(分割符:header和header之间使用换行符分割,header和body之间使用空行分割header之中的键值对通过冒号分割)(不能使用空格充当分割符,若是为字符串,则不满足)】【可以使用\0和\1这样的不可见字符来分割(\0表示ASCII码值为0的,\1表示ASCII值为1的值……叫做不可见字符即正常文档中没有的字符)】【也可以使用Jason方式(类似于python中的字典】【protobuf序列化库,二进制文本字符串格式,使用二进制占用资源少,但是同样调试起来也不方便】【http是纯文本的形式,方便可读,方便进行调试】
sofa:百度开源的RPC框架
ctemplate:谷歌开源的html渲染的框架
cppjieba:中文分词库
使用码云:git clone
E)、gflags的使用:test_gflags这个目录下的文件
F)glog的使用:
G)protobuf的使用:
5、注意:这里实现时,将公共代码放在common中,其他几个代表需要实现的几个模块;front表示前端代码;建立符号链接ln -s ~/third_part将其放在项目目录下
6、索引模块
(1)实现一个索引制作程序
输入:boost所有文档(html)
输出:索引文件(包含了格式化的正排和倒排),后面由搜索服务器进行加载(加载到内存中,直接由搜索服务器从内存中绑定服务器)。
(2)实现索引反解工具:输入:索引文件;输出:把索引文件中的内容进行更加直观更加格式化的输出,方便肉眼进行测试。
(3)实现一个静态库:静态库帮助我们完成公共代码的组织。和索引相关的核心操作都放到静态库中。
索引制作的流程:1)遍历所有需要处理的html,对html进行去标签。把所有文件去标签之后的结果组织到一个文件(raw_input)中,方便后续处理(python);2)读取并分析raw_input文件,制作正排和倒排(cpp)
实现去标签(python html去标签)
c++标准库不支持遍历目录的操作