spring boot 实现搜索引擎的设计思想

news2024/9/21 10:16:57

目录

实现思路

索引模块

预处理

对文档进行分词

搜索模块


实现思路

索引构建模块 + 搜索模块 + 数据库模块

索引模块

        对于搜索一个东西,我们很自然的能想到遍历去查找。比如我要查找一本书叫 《红楼梦》,那么我直接在所有结果中进行遍历查找,当我们找到书名为《红楼梦》的结果时,就代表我们查找到了。但是这样有一个很致命的缺点就是当数据量很大的时候,查找的效率实在太过低下。这种遍历搜索的时间复杂度为O(n),对于搜索引擎这种实时性要求很高的工具来说太慢了

        因此,标准的解决方案是使用倒排索引和正排索引。正排索引就是一个资源 id 与资源内容的映射。由于我们是针对jdk的文档做一个搜索,所以是文档 id 与 文档的映射。我们维护一个 key -value 结构,如图所示:

 倒排索引就是告诉我们文中的一个词出现在哪些文章中,文章id是多少。我们维护的也是一个key-value结构,key是一个词,value是一个集合,集合中是包含这个词的文章id,还会包含一些其他东西,由于我们要对搜索结果进行排序,还需要加入权重属性。如图所示

 然后我们将计算出来的正排索引和倒排索引保存到数据库中,当我们在前端浏览器界面输入一个关键词时,就可以先通过倒排索引得到docId,再根据docId得到相应的文档内容,最终显示再浏览器界面上。

预处理

        扫描根目录下的所有 html 文件,分别拿到每个文件中的 title ,content 和 path 。由于 html 文件中除了我们想要的内容还包含了很多标签,例如 script 标签,html 标签等,因此我们需要按照一定的规则将这些标签全部去除,只保留我们想要的文字信息。

例如上图就有 div 标签 ,code 标签等。

标签都是成对出现的,形如<...>...</...>。根据这个规律,我们可以使用正则表达式进行匹配和替换。

对文档进行分词

        在搜索引擎中,对文档进行分词是很重要的,因为构建正排索引和倒排索引首先需要拿到一个单词。分词是一个很复杂的工作,我们这里采用第三方库去进行分词,虽然准确度可能有所欠缺,但是整体上还是能满足要求的。

        在对html文档进行了预处理的基础上,采用ansj进行分词,需要在pom.xml中引入依赖,依赖如下:

<dependency>
    <groupId>org.ansj</groupId>
    <artifactId>ansj_seg</artifactId>
    <version>5.1.6</version>
</dependency>

        分词库会分析语句的词性,内容等最终得到一个结果集。得到了结果集之后我们就可以对当前文档进行统计,得到 单词集 和 单词出现数量的集合。基于上面两个集合,我们就可以根据权重计算公式计算出当前文档中所有单词的权重,最终得到一个 Map (单词 -> 权重)最后就可以插入数据库了。

搜索模块

        前端界面提供一个搜索框,在搜索框中输入搜索词。后端对输入进行分词处理,如果只有一个词,那么可以直接执行数据库查询操作,将查询结果以 JSON 格式 返回给前端,前端使用 thmeleaf 模板能够方便的显示查询结果列表。如果有多个查询词,需要对每个词进行数据库的查询操作再进行聚合操作,再计算一遍整体的权重。

        针对搜索,我们可以观察到,如果我们直接进行线性的查找,性能会很差。当数量级达到百万时,O(n) 的时间复杂度是不可接受的,尤其是对于搜索引擎这种实时性要求很高的工具。我们可以使用索引来对查询进行优化。即用一定的空间换时间。我们只需再数据库中构建一次索引,之后的查询就可以以O(logn)的时间复杂度进行查询。将原来的百万级别讲到十位数级别。

        在倒排索引中,词 和 权重 都可以被索引优化。因为我们有两个需求即 找到包含查询词的文档 和 对所有包含查询词的文档根据权重进行排序。在索引优化之后,我们避免了每次查询都进行遍历查找和排序从而提高性能。

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

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

相关文章

druid解析-过滤器详解

druid支持过滤器&#xff0c;可以在获取连接或者调用连接对象的方法时&#xff0c;先调用过滤器&#xff0c;之后再执行底层方法&#xff0c;比如DruidDataSource的getConnection()方法&#xff1a; public DruidPooledConnection getConnection(long maxWaitMillis) throws SQ…

网络安全一哥的奇安信发布了全球高级可持续威胁年度报告 值得学习

声明 本文是学习全球高级持续性威胁 APT 2021年度报告. 下载地址而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 中国境内高级持续性威胁综述 基于中国境内海量DNS域名解析和奇安信威胁情报中心失陷检测&#xff08;IOC&#xff09;库的碰撞分析&…

9_1、Java基本语法之常用类String、StringBuffer、StringBuilder的使用

一、String的使用及常用方法 1、概述 String:表示字符串&#xff0c;使用""引起来。 1.1、String类是声明为final的&#xff0c;不可被继承。 1.2、String类实现了Serializable接口&#xff0c;表示字符串支持序列化。 …

【王道操作系统】2.1.3 原语实现对进程的控制

原语实现对进程的控制 文章目录原语实现对进程的控制1.什么是进程控制2.原语实现对进程的控制3.回忆进程的组织4.进程控制大致图解5.进程控制原语的相同点6.进程控制的五种原语1.什么是进程控制 2.原语实现对进程的控制 3.回忆进程的组织 4.进程控制大致图解 这里说明一下调度和…

MySQL【AUTO_INCREMENT 】自增列

使用案例场景再现&#xff1a; 创建一个为test的数据库&#xff0c;为数据库test创建一个数据表student &#xff0c;其中包含的字段有 id name sex&#xff0c;admission_time,其中要求student表中的人员id必须连续排列。 create database test use test cr…

SCI论文解读复现【NO.1】基于Transformer-YOLOv5的侧扫声纳图像水下海洋目标实时检测

此前出了目标改进算法专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读最新目标检测算法论文&#xff0c;帮助…

三旗舰焕新发布引领品牌向上 长城汽车登陆2022广州车展

近日&#xff0c;长城汽车携哈弗、魏牌、欧拉、坦克、长城炮以及沙龙六大品牌&#xff0c;登陆第二十届广州国际汽车展览会&#xff08;以下简称“2022广州车展”&#xff09;。魏牌全新旗舰蓝山DHT-PHEV、坦克500 PHEV长续航版、大型高性能豪华皮卡山海炮等车型联袂而至&#…

创建静态库存文件 ansible(3)

目录 创建一个名为/home/student/ansible/inventory的静态库存文件如下所示&#xff1a; &#xff08;1&#xff09;node1是dev主机组的成员 &#xff08;2&#xff09;node2是test主机组的成员 &#xff08;3&#xff09;node1和node2是prod主机组的成员 &#xff08;4&am…

【Qt】控件——QPlainTextEdit使用简单介绍:常用方法及信号、逐行读取编辑框的内容、使用自带的快捷菜单、作为日志显示窗口

Qt控件-QPlainTextEdit使用 参考链接&#xff1a; https://blog.csdn.net/seniorwizard/article/details/109726147; https://blog.csdn.net/seniorwizard/article/details/109726147 文章目录Qt控件-QPlainTextEdit使用QPlainTextEdit控件简单介绍1. 逐行读取文本编辑框的内容…

【PCB专题】什么是金属化孔(PTH)和非金属化孔(NPTH)

计出来的,并不是放在那里好看的,每个不同的孔洞都有其目的。一般来说孔洞越多,PCB的成本也越高。 PCB中的孔类型大体上可以被区分为PTH(Plating Through Hole)电镀导通孔,和NPTH(None Plating Through Hole)非电镀导通孔两大类。这里说的通孔是指从PCB的一面直接贯穿到…

Spark数据倾斜性能调优

目录 调优概述 数据倾斜发生时的现象 数据倾斜发生的原理 如何定位导致数据倾斜的代码 某个task执行特别慢的情况 某个task莫名其妙内存溢出的情况 查看导致数据倾斜的key的数据分布情况 知识拓展 coalesce 和 repartition 的区别 数据倾斜的解决方案 解决方案一&am…

【哈工大大一年度项目经验与感想】立项篇 中(2021.9.17~2021.11.17)

第四步&#xff1a;立项报告书写 立项报告的目的在于向答辩老师或者投资方阐述你的项目是什么&#xff1f;做什么的&#xff1f;解决什么问题&#xff1f;打算怎么解决这些问题&#xff1f;有什么创新点、特色&#xff1f;目标&#xff1f;所以一篇立项报告正文需要包括以下内容…

21级数据结构考前模拟题

说明&#xff1a; 此试卷为21级数据结构考前模拟题&#xff0c;老师并未给出标准答案&#xff0c;故以下所有答案均为博主给出&#xff0c;并只供参考&#xff0c;不保证其正确性&#xff01;&#xff01;&#xff01; 只更新了部分&#xff0c;还在写题中&#xff01;&#xf…

同步+异步日志系统(C++实现)

对于一个服务器而言&#xff0c;不论是在调试中还是在运行中&#xff0c;都需要通过打日志的方式来记录程序的运行情况。本文设计的日志系统实现了同步与异步两种功能&#xff0c;原理见下图&#xff1a; 同步日志&#xff1a;日志写入函数与工作线程串行执行&#xff0c;由于涉…

人脸识别与美颜算法实战-基于机器学习的人脸识别

机器学习根据输出的类型一般分为两类,分类和回归。分类的输出一般是离散值,回归输出的值一般是连续的。比如,人脸识别这种就属于分类问题,房价预测一般是一个回归问题。 鸢尾花分类 # -*- coding: UTF-8 -*- # 导入数据集 from sklearn.datasets import load_iris iris =…

InnoDB事务原理理解(redo log,undo log,锁,MVCC的理解)

目录事务事务的四大特性ACID事务相关SQL语句事务原理事务如何解决隔离性隔离性总结事务如何解决原子性、一致性、持久性redo log 重做日志CheckPoint 检查点机制Double Writer 双写磁盘undo log 回滚日志锁表级锁表读锁、表写锁元数据锁MDL意向锁行级锁行读锁&#xff0c;行写锁…

coremail邮件安全网关产品详细学习笔记(上)

声明 本文是学习中国企业邮箱安全性研究报告. 下载地址而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 钓鱼邮件 钓鱼邮件的规模 在本章内容中&#xff0c;钓鱼邮件是指含有恶意欺诈信息的邮件&#xff0c;包括OA钓鱼邮件、鱼叉邮件、钓鲸邮件、CEO仿…

PHP代码审计

1. "" 与 “” 在进行比较的时候&#xff0c;会先将字符串类型转化成相同&#xff0c;如果整型跟字符型比较字符或从左往右提取整型直到遇到字符结束&#xff0c;再比较。 在进行比较的时候&#xff0c;会先判断两种字符串的类型是否相等&#xff0c;当等号两边类…

nodejs调用matlab的.m文件

1、问题的提出&#xff1a; 在一些web服务中&#xff0c;后台采用nodejs轻量化服务器接口&#xff0c;而matlab的.m文件编写了算法模块&#xff0c;两者调用时&#xff0c;官方没有提供相应的文档&#xff08;当然也可能我没找到&#xff09;。因此&#xff0c;本文提出了matl…

上岸学姐的浙大MPA复试流程和内容经验介绍

管理类考研笔试落下帷幕&#xff0c;大家有没有因为周末不上课&#xff0c;平时不刷题而感到生活好像缺了些啥呢&#xff1f;没关系&#xff0c;复试已经可以开始准备啦&#xff0c;尤其是对于我们报考MPA项目的同学们来说。 预计二月份下旬笔试成绩会先出来了&#xff0c…