项目日记(3) boost搜索引擎

目录

1. 准备工作

2. 搜索初始化

3. 搜索部分

4. 对content部分处理

5. 服务器编写


前言: 上次在项目日记(2)写了index索引, 这次就可以进行search搜索了. 不多说快看. 先点个一键三联. 蟹蟹!!!

 1. 准备工作

后面需要倒排索引的结构体, 先准备好. words是后面一个文档里面出现的关键字.

    //倒排索引的结构struct InvertedElemPrint{uint64_t doc_id; //文档idint weight;      //文档权重vector<string> words;  //倒排关键字数组;InvertedElemPrint():doc_id(0),weight(0){}};

2.搜索初始化

前面创建的index进行构造单例; InitSearcher:初始化搜索, 就是创建index单例, 以及使用input文档建立索引;这些我们在index的时候都做好了直接引用即可.

class Searcher{private://索引indexns_index::Index* index;public:Searcher(){}~Searcher(){}public://搜索初始化, input就是文档内容//创建单例以及索引void InitSearcher(const string& input){//1.获取或者创建index对象;index = ns_index::Index::GetInstance();cout << "获取index单例成功..." << endl;//2.根据index对象建立索引;index->BuildIndex(input);cout << "建立正排倒排索引成功..." << endl;}

3. 搜索部分

1. 实现对query关键字进行分词; 并且存放到word里面, 前面我们写的util.hpp里面有进行分词的CutString直接使用;

2. 根据不同的分词建立索引, 因为我们在搜索的时候会有大小写, 但是结果是大小写不区分都能查出来.所以使用到boost标准库里面的to_lower接口; 根据关键词进行倒排索引, 通过倒排索引的结果填充倒排信息.

3.合并排序, 一个关键字可能对应多个文档; 根据权重进行排序;

4. 构建json, 根据查找出来的结果, 构建json串, 完成序列化和反序列化;

5. 还要对content的查找的关键字进行截取, GetDesc就是完成这个任务的.

//query是关键字, json_string返回给浏览器搜索结果.void Search(const string& query, string* json_string){//1.分词;将输入的关键字进行分词.并且用word存放vector<string> words;ns_util::JiebaUtil::CutString(query, &words);//2.触发; 根据不同的分词进行index, 忽略大小写.vector<InvertedElemPrint> inverted_list_all;//文档id和倒排结构unordered_map<uint64_t, InvertedElemPrint> tokens_map;for(string word : words){boost::to_lower(word);//根据分词关键字建立倒排索引, ns_index::InvertedList* inverted_lsit = index->GetInvertedIndex(word);//建立失败, 就继续;if(nullptr == inverted_lsit){continue;}//将倒排索引的结果用item接收.插入到文档内for(const auto& elem : *inverted_lsit){auto& item = tokens_map[elem.doc_id];item.doc_id = elem.doc_id;item.weight += elem.weight;item.words.push_back(elem.word); //文档关键字;}}for(const auto& item : tokens_map){inverted_list_all.push_back(move(item.second));}//3.合并排序; 因为一个关键字可能对应多个文档id.//降序;sort(inverted_list_all.begin(), inverted_list_all.end(), \[](const InvertedElemPrint& e1, const InvertedElemPrint& e2)\{return e1.weight > e2.weight;});//4.构建, 根据查找出来的结果,建立json串, jsoncpp, 完成序列化和反序列化;//创建json对象;Json::Value root;for(auto& item : inverted_list_all){//正排索引ns_index::DocInfo* doc = index->GetForwardIndex;if(nullptr == doc){continue;}Json::Value elem;elem["title"] = doc->title;elem["desc"] = GetDesc(doc->content, item.words[0]);elem["url"] = doc->url;elem["id"] = (int)item.doc_id;elem["weight"] = item.weight;root.append(elem);}Json::FastWriter writer;*json_string = writer.write(root);}

 4. 对content部分处理

GetDesc用来截取关键字前后内容的, search是algorithm库里面的接口进行查找.

string GetDesc(const string& html_content, const string& word){//找到word在html_content中首次出现, 以及前面50个和后面100个内容;const int prev_step = 50;const int next_step = 100;//1.找到关键词首次出现的地方;//tolower将大写转小写;auto iter = search(html_content.begin(), html_content.end(), word.begin(), word.end(), [](int x, int y){return (tolower(x) == tolower(y));});if(iter == html_content.end()){return "None1";}//distance返回两个迭代器的距离;int pos = distance(html_content.begin(), iter);//2.获取首次关键词前50到后100的位置;int start = 0;int end = html_content.size() - 1;if(pos > start + prev_step) start = pos - prev_step;if(pos < end - next_step) end = pos + next_step;//3.截取start和end的子串;if(start >= end) return "None2";string desc = html_content.substr(start, end - start);desc +="...";return desc; }

5. 服务器编写

这里使用到httplib的库, 自己可以到gitee里面查找下载到xshell里面就可以使用了.

首先初始化搜索.使用httplib建立库, 服务端获取关键字使用search将数据给json, 再使用客户端传递json.

#include <iostream>
#include "searcher.hpp"
#include "cpp-httplib/httplib.h"//原数据存放的地址;
const string input = "data/raw_html/raw.txt";
//目标网址.
const string root_path = "./wwwroot";int main()
{ns_searcher::Searcher search;search.InitSearcher(input);//使用到httplib库.并且建立服务端.httplib::Server svr;svr.set_base_dir(root_path.c_str());//服务端获取关键字, 使用json把数据读出来.svr.Get("/s", [](const httplib::Request& req, httplib::Response& rsp) {//如果没有输入搜索内容if(!req.has_param("word")){rsp.set_content("必须要输入搜索的关键字!", "text/plain; charset=utf-8");return;}//获取关键字;string word = req.get_param_value("word");cout << "用户在搜索" << word << endl;string json_string;//进行查找.search.Search(word, &json_string);//将内容进行连接.交给服务端.rsp.set_content(json_string, "application/json");});cout << "服务器编写成功..." << endl;svr.listen("0.0.0.0", 8081);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/15090.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三丰云云服务器测评

三丰云是一家知名的云计算服务提供商&#xff0c;提供免费虚拟主机和免费云服务器等多种云计算服务。这些服务深受广大用户的喜爱&#xff0c;因为它们可以帮助用户轻松地搭建网站、应用程序等&#xff0c;同时无需购买昂贵的硬件设备。 对于初学者来说&#xff0c;使用三丰云…

Java重写

方法重写的意义 在java中&#xff0c;子类可以继承父类中的方法&#xff0c;而不需要重新编写相同的方法&#xff0c;但是有时子类并不想原封不动的继承父类方法&#xff0c;需要做一定的修改&#xff0c;这时候就需要使用方法重写 方法重写的定义 在继承的前提下 子类可以根据…

UI面试手册

UI面试手册 薪资&#xff1a;6~9k 高级&#xff1a;8~15k 岗位职责&#xff1a; 负责公司品牌形象及产品相关海报、宣传画等创意设计工作;负责公司日常宣传、营销广告、策划设计制作、产品设计和包装设计等工作&#xff1b;配合国内外广告投放物料设计&#xff0c;按进度要求…

Python使用连接池操作MySQL

测试环境说明&#xff1a;Python版本是 3.8.10 &#xff0c;DBUtils版本是3.1.0 &#xff0c;pymysql版本是1.0.3 首先安装指定版本的连接池库DBUtils 、还有pymysql pip install DBUtils3.1.0 pip install pymysql1.0.3创建文件 sqlConfig.py # sqlConfig.pyimport pymysql…

Math类

类 Math 包含执行基本数值运算的方法&#xff0c;例如基本指数、对数、平方根和三角函数。下面是我写代码时用到的一些字段和方法&#xff0c;归纳如下。 字段 修饰符和类型 Field描述static final double Edouble 值比任何其他值都更接近e, 自然对数的底…

YOLOv10论文解读:实时端到端的目标检测模型

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

618购物节快递量激增,EasyCVR视频智能分析助力快递网点智能升级

随着网络618购物节的到来&#xff0c;物流仓储与快递行业也迎来业务量暴增的情况。驿站网点和快递门店作为物流体系的重要组成部分&#xff0c;其安全性和运营效率日益受到关注。为了提升这些场所的安全防范能力和服务水平&#xff0c;实施视频智能监控方案显得尤为重要。 一、…

蓝桥杯嵌入式国赛笔记(2):拓展板按键程序设计

目录 1、前言 2、电路原理 3、代码编写 3.1 读取Btn电压 3.2 检索按键 3.3 main文件编写 3.3.1 进行变量定义 3.3.2 AD_Key函数 3.3.3 LCD函数 3.3.4 main函数 3.3.5 完整代码 4、测试 5、总结 1、前言 本文进行拓展板按键程序设计&#xff0c;拓展板的按键是通…

人生苦短,我学python之数据类型(下)

个人主页&#xff1a;星纭-CSDN博客 系列文章专栏&#xff1a;Python 踏上取经路&#xff0c;比抵达灵山更重要&#xff01;一起努力一起进步&#xff01; 目录 一.集合 1.1子集与超集 1.2交集&#xff0c;并集&#xff0c;补集&#xff0c;差集 1.intersection(英文&a…

webman使用summernote富文本编辑器

前言 Summernote富文本编辑器功能强大&#xff0c;可以直接从word直接复制内容过来而不破坏原有的文档格式&#xff0c;非常适合做商品详情等内容的编辑工具。本文将展示如何在php高性能框架webman中使用summernote编辑器。 下载 去Bootstrap 中文网、Summernote、jQuery官网…

【设计模式】JAVA Design Patterns——Converter(转换器模式)

&#x1f50d;目的 转换器模式的目的是提供相应类型之间双向转换的通用方法&#xff0c;允许进行干净的实现&#xff0c;而类型之间无需相互了解。此外&#xff0c;Converter模式引入了双向集合映射&#xff0c;从而将样板代码减少到最少 &#x1f50d;解释 真实世界例子 在真实…

低代码开发:拖拽式可视化构建工业物联网系统

什么是低代码&#xff1f; 低代码(Low Code)是一种可视化的软件开发方法&#xff0c;通过最少的手动编码可以更快地交付应用程序。低代码平台的图形用户界面和拖放功能可自动执行开发过程的各个方面&#xff0c;从而消除对传统计算机编程方法的依赖。 什么是低代码平台&#…

Pandas 创建层次化索引

1.创建多层次索引 1.1 隐式构造 最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组 # 导入pandasimport numpy as npimport pandas as pd​data np.random.randint(0,100,size(6,6))​# 行索引index [ ["1班","1班","1班&qu…

如何合理设置Java线程池大小

如何合理设置Java线程池大小&#xff1a;依据任务类型定制策略 Java线程池的合理配置直接关系到系统性能和资源利用率。根据任务性质的不同&#xff0c;合理的线程池大小设置策略也有所区别&#xff0c;主要包括CPU密集型、IO密集型及混合型任务。 1. CPU密集型任务 特点&am…

【全网最全】2024电工杯数学建模B题53页成品论文+完整matlab代码+完整python代码+数据预处理+可视化结果等(后续会更新)

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片链接&#xff0c;那是获取资料的入口&#xff01; 【全网最全】2024电工杯数学建模B题53页成品论文完整matlab、py代码19建模过程代码数据等&#xff08;后续会更新&#xff09;「首先来看看目前已有的资…

微软新功能Recall引发隐私担忧,英国数据监管机构展开调查

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

AP5163 是一款效率高,稳定可靠的 LED 灯恒流驱动控制芯片.

AP5163 特别内置了一个 LDO、其输出电压为 5V&#xff0c;最大可提供 5ma 电流输出。AP5163 采用小 SOT23-6 封装。特别适合宽输入电压范围的应用&#xff0c;其输入电压范围从 5.5V 到 36V。 AP5163 通过一个外接电阻设定输出电流&#xff0c;最大输出电流 3.5A。电流检测精度…

Vue小程序项目知识积累(一)

1.JS中的substring() 方法&#xff1a; substring() 方法用于提取字符串中介于两个指定下标之间的字符,包括空格键。 substring() 方法返回的子串包括 开始 处的字符&#xff0c;但不包括 结束 处的字符。 string.substring(from, to) from&#xff1a;必需。一个非负的整数…

头歌OpenGauss数据库-F.连接查询与子查询第3关:IN、ANY、ALL嵌套子查询

编程要求 我们为你提供了如下数据表&#xff1a; tb_salary表数据&#xff1a; idpositionsalary1Java80002Java84003Java90004Python65005Python10000 根据提供的数据&#xff0c;在右侧编辑器中补充代码&#xff1a; 查询薪资表中比Java最高工资高的所有员工职位名称和薪资&a…

[Spring Cloud] (9)XSS拦截器

文章目录 简述本文涉及代码已开源Fir Cloud 完整项目防XSS攻击必要性&#xff1a;作用&#xff1a; 整体效果后端增加拦截器开关配置pom中增加jsoup依赖添加JSON处理工具类添加xss拦截工具类防XSS-请求拦截器 前端 简述 本文涉及代码已开源 本文网关gateway&#xff0c;微服务…