项目:【Boost搜索引擎】

功能和框架

功能:实现boost文档站内搜索引擎,通过输入查询内容,将与查询内容有关文档的网页按该词的权值降序显示出来,包括标题、内容摘要和网页url,通过点击标题可直接跳转boost库网页进行文档阅读。

框架:
在这里插入图片描述

技术栈和项目环境

技术栈:

c/c++、c++11、STL、准标准库boost、Jsoncpp、cppjieba、cpp-httplib

项目环境:

Linux CentOS 7云服务器、vim/gcc(g++)/Makefile、vscode

在这里插入图片描述

具体实现代码结构

在这里插入图片描述

项目背景

目前市面上的搜索引擎不为少数,例如国内的:百度、搜狗、360;国外的:谷歌、火狐等等。那我们自己实现一个全网的像这样的搜索引擎是不太现实的,但是我们可以实现一个站内的【boost搜索引擎】。

简单介绍一下boost库

Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称。

站内搜索的特点:搜索的数据更垂直,数据量相对较小,比如像cplusplusboost库、甚至像你校内的网站。

并且boost库官网是没有站内搜索的,正好我们自己做一个。

我们先来看一下一个搜索引擎的画面都有什么功能,拿百度举例:
在这里插入图片描述
我们发现每条结果需要三部分组成:
网页的title、网页内容的摘要、即将跳转的网页url

当然你像百度,前几个还有广告。
我们的boost搜索引擎主要针对主要的这3部分。

搜索引擎的宏观原理

在这里插入图片描述

正排索引 倒排索引-搜索引擎具体原理

文档1:小明买了五斤苹果
文档2:小明发布了苹果手机

正排索引:就是由文档ID找到文档内容。

文档ID文档内容
1小明买了五斤苹果
2小明发布了苹果手机

对目标文档进行分词(目的:方便建立倒排索引和查找):

文档1:小明/买了/五斤/苹果/五斤苹果
文档2:小明/发布/了/苹果/手机/苹果手机

停止词:了、的、a、is…一般分词不考虑(最后分词结果去掉停止词)。

倒排索引:根据文档内容进行分词,整理不重复的各个关键字,对应联系到文档ID

关键字(具有唯一性)文档ID(weight权值)
小明文档1, 文档2
文档1
五斤文档1
苹果文档1, 文档2
五斤苹果文档1
发布文档2
苹果手机文档2

模拟一次查找的过程
用户输入:苹果->在倒排索引重查找->提取出文档ID(1、2)->再根据正排索引->找到文档内容->title+content+url->构建相应结果

1、去标签 数据清理模块Parser

  1. 将boost库中的html网页下载到本地src_path
  2. 第一步:EnumFile(src_path, &files_list)递归式的把每个html文件名带路径,保存到vector<std::string> files_list中,方便后期进行一个一个的文件进行读取。
  3. 第二步: ParseHtml(files_list, &results)按照files_list读取每个文件的内容,并进行解析;按照DocInfo_t结构体格式(title、content、url)进行解析,将每一份解析出来的html对象,都保存到vector<DocInfo_t> results里。
  4. 第三步:SaveHtml(results, output)把解析完毕的各个文件内容,写入到output文档中,按照\3作为单个文档的title content url分割符 \n作为各个html文档之间的分隔符。

2、建立索引模块Index

  1. 定义正排索引:vector<DocInfo> forward_index,倒排拉链:vector<InvertedElem> InvertedList,倒排索引:unordered_map<string, InvertedList> inverted_index
  2. 构建索引BuildIndex(const std::string &input)由正排索引和倒排索引构建索引。
  3. 创建正排索引:BuildForwardIndex(const std::string &line),解析文档line,字符串切分Split(line, &results, sep),切分结果填充到结构体DocInfo里,最后插入到正排索引的vector<DocInfo> forward_index
  4. 创建倒排索引:BuildInvertedIndex(const DocInfo &doc)unordered_map<string, word_cnt> wordCnt_map用来暂存词频的映射表,对标题进行分词CutString(doc.title, &title_words),分词结果进行词频统计放入映射表,对文档内容进行分词CutString(doc.content, &content_words),分词结果进行词频统计放入映射表,然后计算权值,构建倒排拉链,最后添加到倒排索引unordered_map<string, InvertedList> inverted_index
  5. 根据doc_id找到找到文档内容GetForwardIndex(uint64_t doc_id),根据关键字string,获得倒排拉链GetInvertedList(const std::string &word)

3、搜索引擎模块 searcher

  1. 首先InitSearcher(const string &input)完成初始化,GetInstance()创建索引index对象,index->BuildIndex(input)根据index对象建立索引。
  2. 根据用户输入的查询词进行搜索Search(const string &query, string *json_string),首先对查询词进行分词CutString(query, &words),再根据分词结果的关键词触发倒排索引GetInvertedList(word),然后合并排序汇总查找结果,按照相关性权值(weight)降序排序sort,之后根据倒排索引的结果,拿到文档ID,通过ID索引到对应文档内容GetForwardIndex(item.doc_id),最终根据查找出来的结果,构建json串输出*json_string = writer.write(root)

4、网络服务模块http-server

  1. 初始化搜索引擎模块InitSearcher(input)
  2. 构建http网络服务对象httplib::Server svr
  3. 设置默认网页根目录svr.set_base_dir(root_path.c_str())
  4. Get获取参数svr.Get()
  5. req获取请求的查询词req.get_param_value("word")
  6. 对查询词进行搜索search.Search(word, &json_string)
  7. rsp将结果输出rsp.set_content(json_string, "application/json")
  8. 服务器打开8081访问端口svr.listen("0.0.0.0", 8081)

5、前后端交互及html页面模块

  1. html实现网页结构骨架。
  2. css实现网页的美化。
  3. js中使用jQuery实现动态效果,ajax实现前后端交互。

项目总结

该项目实现了一个Boost搜索引擎,启动服务器,服务器先进行预处理,将boost库中html数据源进行去标签,解析出标题内容和url。然后根据预处理结果建立正排和倒排索引,服务器启动完毕。用户输入查询内容,服务器进行搜索,将查询内容进行分词,分词结果关键字触发索引找到结果,对结果根据权值的降序排序,最后拼装整合新的页面结果展现给用户,用户可以点击要查看的标题跳转到相关页面。

项目特点和扩展

  1. 该项目的数据源是boost库中doc下的html文件,该数据源是可以随意更换的,用什么数据源,它就是什么搜索引擎。
  2. 该数据源比较固定,可以实现一下在线更新的方案,比如通过爬虫技术,实时监视网页数据内容是否更新,当发现更新,运用操作系统信号知识,同步更新我们服务器上的数据源,当然我们不想因此让服务器关闭,所以可以使用多进程多线程的方案实现。
  3. 该项目会根据用户搜索的内容按关键词权值降序显示,也就是权值高的在最开始。所以我们可以在搜索引擎中添加竞价排名,也就是广告(比如百度),根据谁给的价格高,权衡质量品质,可以调整此广告的权值进行排序。
  4. 另外可以增加登录注册功能,从而引入mysql的使用。

项目网站页面示例

在这里插入图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周周汪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值