业界动态
search_engine:搜索引擎实现
2024-10-31 21:22

目录

search_engine:搜索引擎实现

一.项目背景及原理

1.背景

2.原理

二.技术栈及项目环境

 1.技术栈

2.项目环境

3.环境准备

三.模块划分

四. 遇到的问题及其解决方法

1.搜索结果出现重复文档的问题

2.实现httplib功能的问题

五. 项目特点

1.文档记录

2.竞价排名

3.去掉暂停词

 4.模拟实现httplib库

六. 最终版代码


        前言: 这里实现一个基于boost官方文档的搜索引擎。,但是不只可以用来搜索boost, 修改引入的内容, 就可以变成其它的搜索引擎, 比如可以用来搜索cpp官网文档内容等.

        搜索引擎很多互联网大厂都做过,但是他们做的是由很多人共同完成的大型项目,是一个人没法完成的,不过,可以通过实现一个"小"的搜索引擎,来揣测出这些大型搜索引擎是如何做的。

        这个搜索引擎项目就是在一个网站内搜索,搜索的数据更垂直,数据量更小,实现相对比较简单。

        不过呢,虽然实现的是boost搜索引擎,但是只要修改所引入的文档内容,以及相应的就可以变成其它的搜索引擎,例如JAVA搜索引擎、STL搜索引擎等。

        实现的内容

        我们用百度搜索引擎搜索Boost,可以看到网页的title、网页内容的摘要描述、即将跳转的网站url。

        搜索引擎项目要实现的内容就是这三大块。

① 爬虫程序抓取网页信息:搜索引擎会使用爬虫程序在全网中抓取相关的HTML网页信息,并将其存储在服务器端的磁盘中(这里采用离线下载的方式获取网页信息)。

② 数据预处理:对抓取到的HTML文件进行去标签化和数据清理,即只保留网页文件中的主要信息(标题、正文、URL等)。

③ 建立索引:对预处理后的数据建立索引,以便快速检索。这里的索引包括正排索引和倒排索引。正排索引是根据文档ID查找文档内容,而倒排索引是根据文档内容查找文档ID(建立倒排索引要根据文档内容进行分词, 整理成不重复的多个关键字,再对应到相应的文档ID)。

④ 搜索查询:用户在浏览器中发起HTTP请求,服务端根据请求中的关键字在索引中查找相关文档,并将结果返回给客户端。

        后端:C/C++(C++11), STL, 准标准库Boost, jsoncpp, cppjieba, cpp-httplib

        前端:html, css, js, jQuery, Ajax

        CentOS 7, vim, g++, Makefile, VSCode

boost官方文档: Boost C++ Libraries

下载文档: Index of main/release/1.82.0/source (jfrog.io)

boost库安装: sudo yum install -y boost-devel

cppjieba: GitHub - yanyiwu/cppjieba: "结巴"中文分词的C++版本

注: 安装后, 要将deps下的limonp拷贝一份放到include/cppjieba内

这个安装后可能存在deps下的limonp内无数据, 就要再安装一下limonp: GitHub - yanyiwu/limonp at a269e34dc4948d5a9209e21a7887b52daa0d3e78

安装后把limonp/include下的limonp拷贝到刚才安装的cppjieba的include/cppjieba中


安装方式: 
cppjieba: git clone GitHub - yanyiwu/cppjieba: "结巴"中文分词的C++版本

limonp: git clone GitHub - yanyiwu/limonp: C++ headers(hpp) library with Python style.


使用cppjieba需要使用较新版本的gcc、g++, 可以自行搜索升级方式

jsoncpp安装: sudo yum install -y jsoncpp-devel 

cpp-httplib: cpp-httplib: cpp-httplib - Gitee.com

cpp-httplib安装: git clone cpp-httplib: cpp-httplib

        在搜索模块 searcher 中, 如果根据关键字的各个词检索查找时, 直接创建一个存储倒排拉链的vector数组, 并且在获得当前关键字的倒排拉链后直接插入到这个vector中, 那么就可能出现一个问题: 搜索结果出现重复文档的问题.

        原因: 搜索关键字被jiaba分词后的几个词对应在同一个文档((即同一个doc_id))出现, 导致倒排拉链中存在重复情况. 进而出现了多个一样的搜索结果.

        存在这种问题的搜索模块实现如下

那么如何解决?

        首先需要重新创建一个结构体InvertedElemPrint, 不能再使用之前的index的倒排索引的结构体, 而这个结构体中将原来的string类型的word, 变成了vector<string>类型, 这样这一个结构体如果遇到多个词对应在同一个文档(同一个doc_id)的情况下, 就可以把这多个词都插入到vector数组中. 

        接下来可以创建一个token_map哈希表, 用于doc_id与InvertedElemPrint建立映射关系, 目的是为了根据doc_id去重. 遍历根据doc_id获得到的倒排拉链, 然后创建或获得doc_id在哈希表中所映射的InvertedElemPrint, 然后将InvertedElem内的关键字word放入InvertedElemPrint的vector数组中. 这样即使有doc_id相同的关键字也都会放入同一个vector中, 完成去重的效果.

        最后创建一个存储InvertedElemPrint的vector数组, 并把完成去重后的每一个不重复的doc_id倒排索引放入其中. 用于后面进行合并排序, 汇总查找结果, 并按照相关性权重(weight)降序排序.

        解决问题后的搜索模块实现如下:

        实现httplib的过程中遇到的问题可以说很多,究其原因是对TCP、HTTP、多路转接的理解不够深刻,同时使用经验较少,导致出现了很多的低级错误(包括请求与响应不符合http协议格式的低级错误)。

        解决的方式也很简单,反复查看相关文档,多次理解相关协议与方案,编写代码并反复进行调试与修改。

        文档的作用是为了显示出当前项目的运行情况,是否正常运行,同时也作为一种调试的手段,是很有作用的。

        这里通过实现一个单例类,这个类将标准输出和标准错误的内容重定向到日志文件中,除了该类,又实现了一个日志函数,使用可变参数列表,用来接收不同的日志内容。调用上,只需要在项目执行前,调用类内的enable函数,然后在需要日志的位置,调用LogMessage函数,添加需要的日志即可。

(1)竞价排名定义

        竞价排名是一种按效果付费的网络推广方式, 通过购买相关关键词, 然后给予出价获得竞价排名, 展现给目标用户, 从而获取用户点击.

        很多浏览器都存在竞价排名, 因此这里我也实现一个简单的竞价排名.

(2)实现方法

        首先创建一个文档, 把参与竞价排名的网址url以及出价用 | 分割放入advertise.txt文档中, 每个网址之间用 分隔.

        然后在index中创建advertise_rec哈希表, 用于记录竞价信息. 通过AddAdvertise函数从advertise.txt文档中读取信息并插入到advertise_rec哈希表中. 再实现一个直接返回advertise_rec的函数, 用于将advertise_rec哈希表给到searcher中.

        最后在searcher中先通过index的AddAdvertise函数获取竞价信息, 再获取advertise_rec哈希表, 然后当遍历倒排拉链, 把重复的doc_id合并实现后, 再一次遍历, 判断该关键字对应的文档是否参与竞价排名, 如果参与, 就修改其权重, 并且在title后面加上[广告]标识.

(3)实现

        advertise.txt:

        index:

        searcher:

(4)测试结果

        我们平常在搜索时,无论我们是否写了 "了", "的", "吗" 类似这样的字,搜索出来的结果是没有变化的,因为这些词在搜索中是没有什么作用的,我们想搜的内容是不会因为这些词而发生变化。而去掉这些暂停词之后,会使得搜索变得更快。这里我也实现了该功能。

        通过在util中实现一个JiebaUtil单例类,在进行Jieba分词的过程中,通过将这些词与暂停词文档进行对比,如果是暂停词,就将该词去掉。

        如果使用httplib库,那么http_server这一模块可以很轻松的完成,只需要调用其中的函数即可,但是这个httplib库在实际的公司项目中基本上是不会使用这个httplib库的,因为这个库是存在一些缺点的,可能会出现一些问题。

        因此,这里我自己实现该项目所需用到的相关httplib中的接口,包括TCP和http的实现。

        其中TCP是按照多路转接的方案进行实现的,用到了epoll。

    以上就是本篇文章【search_engine:搜索引擎实现】的全部内容了,欢迎阅览 ! 文章地址:http://dfvalve.xrbh.cn/news/3105.html 
     资讯      企业新闻      行情      企业黄页      同类资讯      首页      网站地图      返回首页 迅博思语资讯移动站 http://keant.xrbh.cn/ , 查看更多   
最新新闻
“撒旦”人血鞋?碰瓷新疆棉花的耐克,又开始喊冤了?
继主动碰瓷新疆棉花把自己搞得股价大跌之后耐克秉承着“no zuo no die”的精神又开始暗搓搓搞“阴间操作”限量发售含人血的“撒
tiktok怎么搭建外网 详细教程及步骤
TikTok怎么搭建外网(详细教程及步骤)TikTok是一款非常流行的短视频社交应用程序,它在全球范围内拥有数亿用户。在使用TikTok的
《以案释法》步数越多,收益越高?别被“走路也能赚钱”的理财广告忽悠了
  走路也能赚到钱的理财  “丑的人还在睡觉,美的人已经跑出一杯星巴克了。”2016年的一天,一个女孩晒出的朋友圈截图引起了
如何用生意参谋算出同行店铺真实销售额
怎么经过生意顾问算出同行店肆实在销售额?大多数在淘宝天猫工作过的人都知道,他们的背景显现了同行商铺的买卖数据,这被称为买
一款最近比较火的网站统计分析系统,易分析具有什么样的功能呢?
一、产品简介北京普艾斯科技有限公司成立于2009年,服务客户1000+,包括电商、金融、保险、政务服务等行业。私有化部署,全渠道
向佐快乐大本营2024年精彩回顾:四年时光共欢笑
张大大谢娜力捧下的综艺新星张大大一位在娱乐圈中颇具人气的主持人他的成名之路离不开谢娜的提携回顾张大大的成名之路可以说谢娜
PingTools app
《PingTools app》是一款非常好用的实用工具软件,软件内拥有丰富的功能,包含了包括浏览器扫描等。使用非常简单,直接下载安装
抖音能看到谁搜索过自己吗?
尊敬的用户,您好。针对抖音平台是否能够查看谁搜索过自己的问题,我们需要做一些详细说明。首先,根据我们了解到的情况,在抖音
什么是人工智能“语料库”?为什么每个人都在谈论它?
编者按:比尔盖茨(Bill Gates)、Reddit 首席执行官和其他科技领袖越来越多地谈论“语料库”,现在是时候了解它是“何方神圣”
LED行业词语中英对应
1、led 灯具构成英文led 球泡灯:led bulbLed 贴片灯珠:SMD LEDLed驱动电源:led driver隔离电源:isolated driver非隔离电源:
本企业新闻

点击拨打: