当前位置: 首页 > article >正文

13.boost项目总结(C++)

项⽬设计:项⽬主要划分成下列模块

a. 数据清洗模块:针对Boost⽂档的HTML进⾏解析,去除html标签,提取出核⼼数据
b. 索引模块:构建正排索引和倒排索引。
c. 搜索模块:基于索引,实现按查询词查找出匹配HTML⽂档的逻辑
d. Web模块:基于cpp-httplib,搭建HTTP服务器,提供HTTP接⼝,编写前端⻚⾯

最终的成果

该项⽬能够达成针对Boost⽂档的搜索预期效果,也就是通过浏览器访问服务器获取搜索⻚⾯,输⼊关键字进⾏搜索,得到预期正确的搜索结果.
通过这个项⽬,进⼀步的了解了搜索引擎的⼯作原理,对Linux,HTTP,⽂件操作,数据结构等核⼼操作的理解有了进⼀步的提⾼,锻炼了项⽬设计,问题解决的能⼒。

使⽤了哪些技术

  • STL:C++常⽤技术
  • cpp-httplib:⾮常轻量的http库.相⽐于cpp-netlib来说,cpp-httplib引⼊的依赖更少,⽆需编译,直接引⼊头⽂件就可以使⽤,⽽且官⽅⽂档简洁清晰,⾮常快速就能上⼿.
  • cppjieba:分词库.在开源免费的分词库中,cppjieba分词效果较好,⽹上的资料⾮常丰富,⾜够满⾜本项⽬的需求.

挑战

针对搜索引擎实现原理的调研:参考了⼀些⽹上的资料和⼀些开源项⽬的代码,发现别⼈介绍/编
写的搜索引擎,功能/流程⼤多⽐较复杂,⽽此处我只需要⼀个⽐较简单的搜索引擎,因此需要对功能进⾏提炼,把最核⼼的部分提取出来并进⾏实现.

扩展

当前是针对boost⽂档进⾏解析和制作索引的.后续也可以引⼊其他的⽂档html,做更丰富搜索功能.
可以通过第三⽅⽹站的api(⽐如github),或者爬⾍爬取对应⽹站的⽹⻚数据,获取到更多的待分析数据.

正排索引和倒排索引的结构

  • 正排索引是docId=>⽂档详细信息的映射
  • 倒排索引是词=>⽂档id列表的映射.

检索的流程

  • 分词:针对⽤⼾输⼊的查询词进⾏分词
  • 触发:根据分词结果,查倒排索引,获取⽂档id列表
  • 归并:针对多个词触发的⽂档id进⾏归并,把相同的id的触发结果合并成⼀个,并提⾼权重。
  • 排序:根据权重的值降序排序
  • 包装结果:根据⽂档id,去正排索引中查找,⽣成描述,最终构造出完整的返回结果。

如何实现的分词?分词原理是什么

基于词典

中⽂语⾔词汇虽然数⽬众多,但是对于计算机来说是可以穷尽枚举的。

基于概率统计

根据语料库进⾏训练(⽐如近20年⼈⺠⽇报的所有内容),统计相邻两个汉字出现的概率,将概率⾼的汉字组合更新进⼊词典
当前直接使⽤了第三⽅库cppjieba,并未关注具体分词算法的实现

制作索引的流程是什么样⼦的

  • 数据清洗:遍历⽬录,读取到每个html⽂件内容,提取出html中的标题,正⽂,url
  • 构建正排索引:把上个环节解析出的内容,构造成⽂档对象,通过⼀个数组管理起来。对应的数组下标设定为"⽂档id"。此时就得到了⽂档id=>⽂档内容的映射
  • 构建倒排索引:针对每个⽂档对象的标题和正⽂,进⾏分词。以分词结果作为key,以⽂档id列表作为value,添加到⼀个哈希表中。此时就得到了词=>⽂档id列表的映射
  • 在构建倒排过程中,同时统计每个词在该⽂档中出现的次数,作为后续排序依据(权重)

词和⽂档的相关性如何衡量

通过词频衡量。当前使⽤的公式是标题中出现的次数*10+正⽂中出现的次数来作为权重.

例如⼀次输⼊两个词A和B,如果A和B的倒排拉链中都包含同⼀个⽂档,此时如何处理

这样的⽂档包含多个查询词,相关性理解成更⾼,应该要排到更靠前的位置。
⼀个简单的做法是针对同⼀个⽂档进⾏权重合并。
⽐如遍历A的倒排拉链,把这⾥的⽂档信息记录到⼀个哈希表中。然后再遍历B的倒排拉链,依次在A中
查询如果发现存在相同的⽂档,则把两个⽂档的权重进⾏相加,并且在最终合并多个拉链时进⾏去重

搜索结果是如何排序的?

  • 在进⾏构建倒排索引的时候,针对⽂档中分词后的词频对每⼀个关键字进⾏了权重计算(标题与正⽂中的关键字权重不同)
  • 在查询的时候,根据查询关键字进⾏倒排索引查询时,根据得到的倒排拉链中的关键字权重进⾏⽂档权重统计(因为有可能多个关键字对应同⼀个⽂档,因此将同⼀个⽂档中的多个关键字权重进⾏求和)
  • 在返回结果的时候,对返回的内容按照⽂档权重进⾏编号排序后返回

http服务器是如何搭建的

  1. 在⽹上查找⼀些开源的HTTP库,其中找到了httplib,mongoose,httpd,…等⼀些轻量的http库,经过对⼏个库的使⽤以及源码的了解,决定使⽤httplib库。httplib库有以下优点:
    a. 是⼀个单头⽂件实现的库,使⽤简单,只需要clone仓库后包含⼀个头⽂件即可,⽆需其他安装以及库的链接。
    b. 实现上基于select(win)或其他多路转接技术实现描述符I/O事件监控,采⽤线程池对就绪的
    描述符进⾏后续处理。
    c. 代码编写层次逻辑清晰,其内部构造了URI正则表达式和请求处理回调函数的映射路由表,只需要使⽤时实现了业务处理函数,并提前设定好指定请求的处理回调函数就可以通过简单的⼗⼏⾏代码完成服务器的搭建。
    d. 基于C++实现,嵌⼊在当前项⽬中更加合适(mongoose基于C++实现,但是使⽤上没有httplib简单,⽽httpd基于C语⾔实现,不是说不好,只是httplib⽤起来更轻松)

http://www.kler.cn/a/581242.html

相关文章:

  • CoreWeave:从“微软专供”到OpenAI的座上宾
  • WPF 元素周期表
  • c++学习之QT综合项目一
  • Vue使用ScreenFull插件实现全屏切换
  • 基于STM32的智能家居门禁开锁控制系统(论文+源码)
  • 可复用的 Vue 轮播图组件
  • Unity 基础知识总结(持续更新中...)
  • SwiftUI 让视图自适应高度的 6 种方法(四)
  • 03_NLP常用的文本数据分析处理方法
  • 【AI落地应用实战】RAGFlow + 知识图谱Knowledge Graph + Deepseek + 知识库构建初步探索
  • Codeforces Round 1008 (Div. 2)(A-D)
  • Application.OnTime如何引用带参数的过程
  • 数据篇| App爬虫入门(一)
  • Python数据分析之机器学习基础
  • WinForm模态与非模态窗体
  • 刚刚!微调 DeepSeek 满血版正式开源。。。
  • 基于PyTorch的深度学习——机器学习3
  • 运维无忧:NebulaGraph Dashboard—— 集群监控的可视化神兵
  • okhttp源码解析
  • 【leetcode100】分割回文串