简易搜索引擎SEWeibo

背景

有一组微博事件数据,之前做了一些数据分析与挖掘的工作。想着用C++做一个简单的搜索引擎玩玩。

亮点:

  • 搜索支持关系关键字作为搜索条件,以文本情感极性作为初筛条件,以TF-IDF为搜索排序依据
  • 以Reactor模式为基础,实现C++后台,支持线程池、支持epoll实现I/O多路复用
  • 实现一个简单的前端,搭载在apache上
  • 引入redis实现缓存,引入日志系统

详细代码请到github:https://github.com/li-car-fei/SEWeibo

求求点个star~~

搜索关键步骤实现

预处理阶段:

  • 使用cppjieba对每个微博事件进行分词
  • 分词后计算每个事件的词频,并且根据情感词典计算每个事件的情感倾向分
  • 根据TF-IDF计算每个词在其出现的事件中的影响权重

实际搜索阶段:

  • 解析出搜索语句中的关键字:ANDORNOT
  • 按照搜索关键字分割搜索语句,并进行搜索,三个关键字分别对应搜索结果求交集、并集、非集
  • 将搜索语句视为一个事件,对其进行分词,计算词频、情感得分
  • 初筛:筛选出拥有搜索语句中所有词语的事件,并选出情感倾向与搜索语句相同的事件
  • 再筛:根据搜索语句的每个词语的权重值构成向量,再计算与备选集的余弦相似度,选取最相似的前k个返回
  • 根据搜索结果的事件ID,生成摘要并返回结果
  • redis 缓存

结果示例




Log 日志:

2023-11-10 17:06:15,951: INFO rootCategory : Log init success
2023-11-10 17:06:17,226: INFO rootCategory : cppjieba init!
2023-11-10 17:06:21,692: INFO rootCategory : 停词库,情感词表,网页库,偏移库,倒排索引库,情感得分表 读取数据成功!
2023-11-10 17:06:28,979: INFO rootCategory : >>client has connected 127.0.0.1:9006 >> 127.0.0.1:34133
2023-11-10 17:06:28,979: INFO rootCategory : search event: 蔡徐坤
2023-11-10 17:06:28,980: INFO rootCategory : redis key exists: 蔡徐坤
2023-11-10 17:06:28,980: INFO rootCategory : >>client has broken up 127.0.0.1:9006 >> 127.0.0.1:34133
...

细节

前端
  • 前端简单写的页面,用apache搭载,详见frontend文件夹
  • 后端返回json数据,前端用jquery进行解析渲染
单 Reactor 多线程模式
  • net 中实现 Reactor 相关、TCPConnection 相关;由 Acceptor 负责主线程连接相关,监听新的连接请求;回调函数挂载到 TCPConnection 上,由 EventLoop 从 epoll 中取出可操作的 socket 句柄,再调用 TCPConnection 中的回调函数进行处理;
  • threadpool 实现线程池,由回调函数中将业务处理函数添加到线程池的任务队列中,是和 Server 分离开的,不影响 Server 主线程监听连接;
  • using Task = function<void()>; 定义了添加到线程池任务队列的数据类型,是一个可调用对象(函数、函数指针、lambda表达式等皆可)
redis 缓存
  • 单例模式实现,将搜索语句与结果的JSON语句存储到缓存中
  • 在计算搜索匹配结果、词频、情感前先从缓存中查找有没有相应的key(即搜索语句文本),有则直接返回
  • 用于搜索运算消耗较大,使用缓存可以很好提高性能
log 日志
  • 基于log4cpp实现日志,单例模式
  • 在头文件中定义相应的宏,以实现简单调用日志接口
搜索细节
  • 关键字分割搜索语句,不同关键字对应不同的搜索结果合并
  • 首先搜索出包含搜索文本每个词的事件,并依据情感得分去除情感倾向不同的结果
  • 根据搜索规则匹配,合并得到搜索结果
  • 根据搜索语句的TF-IDF向量与搜索结果事件的向量计算余弦相似度并排序
  • 最终生成摘要并返回结果
// 执行查询
    void WordQuery::doQuery(RedisClient& redisClient, const string &s, const TcpConnectionPtr &ptr)
    {
        // 先查询缓存
        auto redisResult = redisClient.get(s);
        if (redisResult.first)
        {
            ptr->sendInEventLoop(redisResult.second);
            return;
        }

        // 提取关键字和搜索文本
        auto parseSearchTextResult = parseSearch(s);

        /**
         * 构建返回结果所需:
         *  (1)set<int> eventIds:事件id
         *  (2)map<int, map<string, int>> wordsMap : 词频记录(当前搜索语句所构建的event的) 
         *  (3)map<int, vector<pair<string, double>>> vec :每个词与其权重(当前搜索语句所构建的event的) 
        */

        set<int> eventIds;
        map<int, map<string, int>> wordsMaps;
        map<int, vector<pair<string, double>>> vecs;

        // 循环遍历关键字和搜索文本,构建结果
        searchThrough(eventIds, wordsMaps, vecs, parseSearchTextResult.first, parseSearchTextResult.second);

        // 根据第一个搜索map和搜索文本的vec 计算余弦排序,形成摘要
        string message = doReturn(eventIds, wordsMaps.begin()->second, vecs.begin()->second, ptr);

        // 设置缓存
        redisClient.set(s, message);

    }
依赖库
  • cppjieba:常用中文分词库
  • limonp:cppjieba中依赖的
  • jsoncpp:json相关实现

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电源电压范 围宽、功耗小、抗干扰能力强的国产芯片GS069适用于电动工具等产品中,采用SOP8的封装形式封装

GS069电动工具直流调速电路是CMOS专用集成电路&#xff0c;具有电源电压范 围宽、功耗小、抗干扰能力强等特点。通过外接电阻网络&#xff0c;改变与之相接 的VMOS 管的输出&#xff0c;达到控制电动工具转速的作用。该电路输出幅值宽&#xff0c; 频率变化小&#xff0c;占空比…

linux系统下如何获取文件的创建时间

1. ll 或 ls -l config.json 查看时间 2. 使用stat 查看创建时间 access time&#xff1a;表示我们最后一次访问&#xff08;仅仅是访问&#xff0c;没有改动&#xff09;文件的时间 modify time&#xff1a;表示我们最后一次修改文件的时间 change time&#xff1a;表示我们最…

2023 PostgreSQL 数据库生态大会:解读拓数派大数据计算系统及其云存储底座

11月3日-5日&#xff0c;由中国开源软件推进联盟 PostgreSQL 分会主办的中国 PostgreSQL 数据库生态大会在北京中科院软件所隆重举行。大会以”极速进化融合新生”为主题&#xff0c;从线下会场和线上直播两种方式展开&#xff0c;邀请了数十位院士、教授、高管和社群专家&…

【Flink】Flink任务缺失Jobmanager日志的问题排查

Flink任务缺失Jobmanager日志的问题排查 问题不是大问题&#xff0c;不是什么代码级别的高深问题&#xff0c;也没有影响任务运行&#xff0c;纯粹因为人员粗心导致&#xff0c;记录一下排查的过程。 问题描述 一个生产环境的奇怪问题&#xff0c;环境是flink1.15.0 on yarn…

音画欣赏|《纯洁的梦乡》

《纯洁的梦乡》 80x60cm 陈可之2021年绘 题龙阳县青草湖 【元】唐温如 西风吹老洞庭波&#xff0c;一夜湘君白发多。 醉后不知天在水&#xff0c;满船清梦压星河。 车遥遥篇 【宋】范成大 车遥遥&#xff0c;马憧憧。 君游东山东复东&#xff0c;安得奋飞逐西风。 愿我如星…

自定义windows右键菜单,软件卸载后 右键菜单残留 打开方式残留 解决方法

问题&#xff1a; 更改windows右键菜单软件卸载残留&#xff0c;其仍然出现在文件的打开方式列表&#xff0c;右键菜单中。 解决方法1&#xff1a;推荐使用registry workshop批量搜索删除注册表 绿色版&#xff1a; 蓝奏云&#xff1a;https://wwzd.lanzouw.com/iPJNp1em339…

centos下安装mysql8版本

1、如果服务器没有wget&#xff0c;先下载wget工具 sudo yum install wget 2、下载指定mysql版本的tar包 sudo wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.21-1.el7.x86_64.rpm-bundle.tar 3、解压tar包 sudo tar -xvf mysql-8.0.21-1.el7.x86_64.rpm…

第三篇 基于JSP 技术的网上购书系统—— 数据库系统设计(网上商城、仿淘宝、当当、亚马逊)

目录 1.逻辑关系设计 2.物理设计 2.1管理员表 2.2留言表 2.3会员登录表 2.4会员表 2.5订单表 2.6订单商品表 2.7产品表 2.8产品货架表 2.9收藏表 2.10类别表 2.11新闻表 数据库系统是用来保存数据的软件系统&#xff0c;当今比较流行的数据库系统&#xff0c;如 MS…

学好Python-新手小白如何做?

新手小白如何学好Python?有哪些参考方法吗?这是一个老生常谈的话题了。今天为大家带来两位前辈的分享&#xff0c;他们给出了非常实用的方法和思路&#xff0c;希望对你有所帮助。 1、多练&#xff0c;两个字&#xff1a;多练 如果真的要说方法可以参考如下&#xff1a; ①…

直流有刷电机调速电路,输出端内置14V钳位结构,具有电源电压范围宽、功耗小、抗干扰能力强等功能的国产芯片GS016的描述

GS016是一款直流有刷电机调速电路&#xff0c;输出端内置14V钳位结构&#xff0c;具 有电源电压范围宽、功耗小、抗干扰能力强等特点。通过桥接内部电阻网 络&#xff0c;可以改变PWM占空比输出&#xff0c;达到控制电机转速作用。GS016采用SOP14的封装形式封装。 主要特点&am…

数据结构笔记 B 树 B+树

1 B树 Balanced 树&#xff0c;多路平衡搜索树 1.1 特征 一个m阶的B树具有如下几个特征&#xff1a; 根结点的儿子数为[2, M]&#xff1b;除根结点以外的非叶子结点的儿子数为[M/2, M]&#xff1b;(M/2向上取整&#xff09;每个结点存放至少M/2-1&#xff08;M/2向上取整&a…

在Ubuntu系统上部署Inis博客,并使用内网穿透将博客网站发布到公共互联网上

文章目录 前言1. Inis博客网站搭建1.1. Inis博客网站下载和安装1.2 Inis博客网站测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总…

Pandas画图报错:ValueError: signal only works in main thread

Pandas画图报错&#xff1a;ValueError: signal only works in main thread 基于Django 解决方法 按如下方式运行服务器 python manage.py runserver --nothreading --noreload

录音频用什么软件?助你轻松捕捉声音!

“有没有什么录音频的软件推荐呀&#xff1f;学校要求拍摄一个关于交通安全的纪录片&#xff0c;现在视频拍摄好了&#xff0c;音频却出了问题&#xff0c;需要重新补录声音&#xff0c;但是找不到合适的录音频软件&#xff0c;有人知道吗&#xff1f;” 录制音频是我们在工作…

Linux共享内存

共享内存&#xff1a;进程直接访问共享内存&#xff0c;由使用者进行访问控制&#xff08;互斥等&#xff09; 使用ipcs命令查看系统共享内存 POSIX 共享内存 有名共享内存 多个进程通过共享内存的名字来获取同一块共享内存&#xff0c;实现共享 #include <stdio.h>…

沉醉于代码的境界:探寻计算机书籍的奇妙之旅

文章目录 书中的代码乐章科技解密的乐趣技术指南的引路明灯书籍带给我的启示结语 &#x1f389;欢迎来到数据结构学习专栏~沉醉于代码的境界&#xff1a;探寻计算机书籍的奇妙之旅 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f38…

修改 jar 包中的源码方式

在我们开发的过程中&#xff0c;我们有时候想要修改jar中的代码&#xff0c;方便我们调试或或者作为生产代码打包上线&#xff0c;但是在IDEA中&#xff0c;jar包中的文件都是read-only&#xff08;只读模式&#xff09;。那如何我们才能去修改jar包中的源码呢&#xff1f; 1.…

【App测试】adb三大连接方式-夜神模拟器+真机+android真机(详细步骤)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 adb连接安卓模拟器…

如何驾驭逻辑、形式逻辑与AI算法?

逻辑错误与逻辑形式错误是有区别的&#xff1a; 逻辑错误经常表现为没有逻辑因果&#xff0c;用辩证法、阴谋论和统计归纳替代因果演绎&#xff1b;而逻辑形式错误是&#xff1a;前提是形式和内容需要分离&#xff0c;就像数学与语文分开&#xff0c;数学代表形式&#xff0c;…

从3大维度9个细节聊一聊,边缘计算盒子如何选型

人工智能的蓬勃发展&#xff0c;物联网设备的部署和5G无线技术的到来&#xff0c;越来越多的新兴场景对智能化应用提出了低时延、低带宽、本地化、高安全、低成本的处理需求&#xff0c;包括智慧城市、智慧金融、智慧校园等领域&#xff0c;以及智慧交通、智慧工厂、智慧医疗等…