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

使用ElasticSearch实现全文检索

文章目录

  • 全文检索
    • 任务描述
    • 技术难点
    • 任务目标
    • 实现过程
      • 1. java读取Json文件,并导入MySQL数据库中
      • 2. 利用Logstah完成MySQL到ES的数据同步
      • 3. 开始编写功能接口
        • 3.1 全文检索接口
        • 3.2 查询详情
      • 4. 前端调用

全文检索

任务描述

  • 在获取到数据之后如何在ES中进行数据建模,以方便之后搜索接口的实现
  • 接下来,要考虑的问题是,如何实现MySQL和ES的数据同步
  • 接下来是技术实现,要如何实现基于关键词进行全文检索和对于某一条数据的查询详情
  • 在接口实现之后,前端调用后端暴露的接口来进行数据获取,并在页面进行展示

技术难点

  • 数据同步
  • ES的检索的实现
  • 精确定位MySQL表中的数据

任务目标

  • 根据关键词进行全文检索
  • 查询详情

实现过程

1. java读取Json文件,并导入MySQL数据库中

public List<Workticket> getWorkticket(){ObjectMapper objectMapper = new ObjectMapper();List<Workticket> jsonObjects = null;try {jsonObjects = objectMapper.readValue(new File("D:\\data_hanchuan\\workticket.json"), List.class);} catch (IOException e) {e.printStackTrace();}return jsonObjects;}

​ 上述代码将json文件的数据封装成对象,然后调用MP的批量增加方法(deviceService.saveBatch(list);),将其添加到hanchuan数据库中

2. 利用Logstah完成MySQL到ES的数据同步

【注】Logstash、ES以及Kibana必须版本一致

主要参考logstash这篇博客,完成从MySQL到ES的数据同步。下面是其中的一张表的 .conf文件(几张表就对应几个conf文件)

input {stdin {}jdbc {type => "jdbc"# 数据库连接地址jdbc_connection_string => "jdbc:mysql://localhost:3306/hanchuan?characterEncoding=UTF-8&autoReconnect=true&allowPublicKeyRetrieval=true"# 数据库连接账号密码;jdbc_user => "root"jdbc_password => "root"# MySQL依赖包路径;jdbc_driver_library => "D:\apply_soft\elasticsearch_all_soft\logstash-7.6.1\bin\result\mysql-connector-j-8.0.31.jar"# the name of the driver class for mysqljdbc_driver_class => "com.mysql.jdbc.Driver"# 数据库重连尝试次数connection_retry_attempts => "3"# 判断数据库连接是否可用,默认false不开启jdbc_validate_connection => "true"# 数据库连接可用校验超时时间,默认3600Sjdbc_validation_timeout => "3600"# 开启分页查询(默认false不开启);jdbc_paging_enabled => "true"# 单次分页查询条数(默认100000,若字段较多且更新频率较高,建议调低此值);jdbc_page_size => "3000"# statement为查询数据sql,如果sql较复杂,建议配通过statement_filepath配置sql文件的存放路径;# sql_last_value为内置的变量,存放上次查询结果中最后一条数据tracking_column的值,此处即为ModifyTime;# statement_filepath => "mysql/jdbc.sql"statement => "SELECT id,defective_appearance,leakage_type,anbiao1,subsystem,duty_group,anbiao2,defective_why,elimination_person,department,accept_describe,accept_group from defect where id > :sql_last_value order by id desc"# 是否将字段名转换为小写,默认true(如果有数据序列化、反序列化需求,建议改为false);lowercase_column_names => false# Value can be any of: fatal,error,warn,info,debug,默认info;sql_log_level => warn## 是否记录上次执行结果,true表示会将上次执行结果的tracking_column字段的值保存到last_run_metadata_path指定的文件中;record_last_run => true# 需要记录查询结果某字段的值时,此字段为true,否则默认tracking_column为timestamp的值;use_column_value => true# 需要记录的字段,用于增量同步,需是数据库字段tracking_column => "id"# record_last_run上次数据存放位置;last_run_metadata_path => "result/defect/last_id.txt"# 是否清除last_run_metadata_path的记录,需要增量同步时此字段必须为false;clean_run => false## 同步频率(分 时 天 月 年),默认每分钟同步一次;schedule => "* * * * *"}
}filter {mutate {  //挑选其中的一个字段充当title字段rename => {"defective_appearance" => "title"}	//将其id值设置为”数据库表名001_id“ 方便之后查询详情接口的实现update => {"id" => "defect001_%{id}"}// 将其他字段填充到message字段当中add_field => {"message" =>["%{title};%{leakage_type};%{anbiao1};%{subsystem};%{duty_group};%{anbiao2};%{defective_why};%{elimination_person};%{department};%{accept_describe};%{accept_group};"]}//将多余字段删除,使表的结构始终呈现为{id,title,message}形式remove_field => ["leakage_type","anbiao1","subsystem","duty_group","anbiao2","defective_why","elimination_person","department","accept_describe","accept_group"]}}output {elasticsearch {# host => "192.168.1.1"# port => "9200"# 配置ES集群地址hosts => ["localhost:9200"]# 索引名字,必须小写index => "hanchuan001"}stdout {codec => json_lines}
}

最终我们ES中的数据结构就是下面这个样子

在这里插入图片描述

3. 开始编写功能接口

3.1 全文检索接口
@Overridepublic MetaTotal searchAllHighLight(String msg, int pageNo, int pageSize) throws IOException {if (pageNo <= 1) {pageNo = 1;}SearchRequest request = new SearchRequest(resultIndex);
//      进行搜索SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();boolQueryBuilder.must(QueryBuilders.matchQuery("message", msg)).should(QueryBuilders.matchQuery("title", msg));//        sourceBuilder.size(2000);//        分页sourceBuilder.from(pageNo);sourceBuilder.size(pageSize);//        进行高亮设置HighlightBuilder highlightBuilder = new HighlightBuilder();HighlightBuilder.Field field = new HighlightBuilder.Field("message").preTags("<span style='color:red'>").postTags("</span>");HighlightBuilder.Field field1 = new HighlightBuilder.Field("title").preTags("<span style='color:red'>").postTags("</span>");highlightBuilder.field(field).field(field1);sourceBuilder.query(boolQueryBuilder);sourceBuilder.highlighter(highlightBuilder);//        加入到request中request.source(sourceBuilder);SearchResponse response = client.search(request, RequestOptions.DEFAULT);List<Meta> list = new ArrayList<>();for (SearchHit hit : response.getHits().getHits()) {//----进行高亮字段的替换Map<String, HighlightField> highlightFields = hit.getHighlightFields();HighlightField message = highlightFields.get("message");HighlightField title = highlightFields.get("title");//          未高亮之前的结果Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//            1.找到message中出现关键字的地方进行高亮替换if (message != null) {Text[] fragments = message.fragments();String n_mess = "";for (Text text : fragments) {n_mess += text;}sourceAsMap.put("message", n_mess);}
//            2.找到title中出现关键字的地方进行高亮替换if (title != null) {Text[] fragments = title.fragments();String n_title = "";for (Text text : fragments) {n_title += text;}sourceAsMap.put("title", n_title);}//----结束----Meta meta = new Meta();try {BeanUtils.populate(meta, hit.getSourceAsMap());} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);}list.add(meta);}MetaTotal metas = new MetaTotal();metas.setList(list);metas.setTotal(response.getHits().getTotalHits().value);System.out.println(metas.getTotal() + "总记录数");return metas;}

在业务逻辑代码写好之后在控制层暴露接口

	@ResponseBody@GetMapping("/search/{keyword}/{pageNo}/{pageSize}")public Result searchByMsg(@PathVariable String keyword,@PathVariable int pageNo,@PathVariable int pageSize) throws IOException {MetaTotal metas = service.searchAllHighLight(keyword,pageNo,pageSize);Page<Meta> page = new Page<>(pageNo,pageSize);page.setRecords(metas.getList());page.setTotal(metas.getTotal());return new Result().code(200).message("查询成功").data("list",metas.getList()).data("total",metas.getTotal());}
3.2 查询详情

根据前端传递的id值,进行解析,找到对应的数据库表,进行详情查看。

	@RequestMapping("/details/{id}")@ResponseBodypublic Result look_details2(@PathVariable("id") String id, Map<String,Object> map){String[] str = id.split("001_");if (str[0].equals("defect")){Defect defect = defectService.getById(str[1]);return new Result().code(200).message("详情结果").data("details",defect);} else if (str[0].equals("device")) {Device device = deviceService.getById(str[1]);return new Result().code(200).message("详情结果").data("details",device);} else if (str[0].equals("riskcontroller")) {Riskcontroller riskcontroller = riskControllerService.getById(str[1]);return new Result().code(200).message("详情结果").data("details",riskcontroller);}else if (str[0].equals("security")) {Security security = securityService.getById(str[1]);return new Result().code(200).message("详情结果").data("details",security);}else if (str[0].equals("workticket")) {Workticket workticket = workticketService.getById(str[1]);return new Result().code(200).message("详情结果").data("details",workticket);}return new Result().code(500).message("查询失败");}

4. 前端调用

在这里插入图片描述
在这里插入图片描述

相关文章:

使用ElasticSearch实现全文检索

文章目录 全文检索任务描述技术难点任务目标实现过程1. java读取Json文件&#xff0c;并导入MySQL数据库中2. 利用Logstah完成MySQL到ES的数据同步3. 开始编写功能接口3.1 全文检索接口3.2 查询详情 4. 前端调用 全文检索 任务描述 在获取到数据之后如何在ES中进行数据建模&a…...

通过k-means对相似度较高的语句进行分类

本文介绍了如何使用K-Means算法对相似度较高的语句进行分类&#xff0c;并附上java案例代码 import java.util.ArrayList; import java.util.List; import java.util.Random;public class KMeansTextClustering {public static void main(String[] args) {// 初始化语句数据集…...

国信华源科技赋能长江蓄滞洪区水闸管护项目验收成果报道

“碧水悠悠绕古城&#xff0c;闸启长江万象新。”近日&#xff0c;由北京国信华源科技有限公司倾力打造的万里长江蓄滞洪区水闸管护项目&#xff0c;圆满通过验收&#xff0c;为这片鱼米之乡的防洪安全注入了新的科技活力。 长江之畔&#xff0c;水闸挺立&#xff0c;犹如干堤上…...

HTML:表格重点

用表格就用table caption为该表上部信息&#xff0c;用来说明表的作用 thead为表头主要信息&#xff0c;效果加粗 tbody为表格中的主体内容 tr是 table row 表格的行 td是table data th是table heading表格标题 &#xff0c;一般表格第一行的数据都是table heading...

wine的使用方法

wine版本 所有分支&#xff0c;新的主要版本&#xff1a; wine-x.0 All branches, release candidates:各分支、候选版本&#xff1a; wine-x.0-rcn Stable branch updates: 稳定分支更新&#xff1a; wine-x.0.z Development branch updates: wine-x.y wine *.exe “更改目…...

Linux服务器离线安装unzip包

Linux服务器离线安装unzip包 1. 安装unzip包的目的 解压Docker部署包和服务部署包。 2. 查看当前环境是否已经安装unzip rpm -qa | grep --color unzip3. 下载对应的离线包 地址&#xff1a;http://www.rpmfind.net/linux/rpm2html/search.php?query&submitSearch 例…...

Excel拆分脚本

Excel拆分 工作表按行拆分为工作薄 工作表按行拆分为工作薄 打开要拆分的Excel文件&#xff0c;使用快捷键&#xff08;AltF11&#xff09;打开脚本界面&#xff0c;选择要拆分的sheet&#xff0c;打开Module&#xff0c;在Module中输入脚本代码&#xff0c;然后运行脚本 Su…...

Mybatis---事务

目录 引入 一、事务存在的意义 1.事务是什么&#xff1f; 2.Mybatis关于事务的管理 程序员自己控制处理的提交和回滚 引入 一、事务存在的意义 1.事务是什么&#xff1f; 多个操作同时进行,那么同时成功&#xff0c;那么同时失败。这就是事务。 事务有四个特性&#xf…...

企业直播间媒体分发新闻转播拉流推广名单(金融财经科技类)

【本篇由 言同数字媒体直播分发 原创】随着直播与短视频成为各大企业营销的重要手段&#xff0c;如何选择合适的视频平台进行内容分发与拉流成为了企业关注的焦点。对于财经和科技类企业而言&#xff0c;选择具有专业受众群体和广泛传播能力的平台尤为重要。下面是一些可以帮助…...

华为FreeBuds Pro 4丢了如何找回?(附查找功能使用方法)

华为FreeBuds Pro 4查找到底怎么用&#xff1f;华为FreeBuds Pro 4有星闪精确查找和离线查找&#xff0c;离线查找功能涵盖播放铃声、导航定位、星闪精确查找、上线通知、丢失模式、遗落提醒等。星闪精确查找是离线查找的子功能&#xff0c;当前仅华为FreeBuds Pro 4充电盒支持…...

若依微服务登录密码加密传输解决方案

文章目录 一、需求提出二、应用场景三、解决思路四、注意事项五、完整代码第一步&#xff1a;前端对密码进行加密第二步&#xff1a;后端工具类实现 RSA 加解密功能第三步&#xff1a;登录接口中添加解密逻辑 六、运行结果总结 一、需求提出 在默认情况下&#xff0c;RuoYi 微…...

NVR小程序接入平台/设备EasyNVR深度解析H.265与H.264编码视频接入的区别

随着科技的飞速发展和社会的不断进步&#xff0c;视频压缩编码技术已经成为视频传输和存储中不可或缺的一部分。在众多编码标准中&#xff0c;H.265和H.264是最为重要的两种。今天我们来将深入分析H.265与H.264编码的区别。 一、H.265与H.264编码的区别 1、比特率与分辨率 H.…...

Redisson常用方法

Redisson 参考: 原文链接 定义&#xff1a;Redisson 是一个用于与 Redis 进行交互的 Java 客户端库 优点&#xff1a;很多 1. 入门 1.1 安装 <!--redission--> <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifa…...

html自带的input年月日(date) /时间(datetime-local)/星期(week)/月份(month)/时间(time)控件

年月日期控件 type"date" <input type"date" id"StartDate" valueDateTime.Now.ToString("yyyy-MM-dd") /> //设置值 $("#StartDate").val("2024-12-12"); //获取值 var StartDate$("#StartDate&quo…...

CSS系列(12)-- 响应式设计详解

前端技术探索系列&#xff1a;CSS 响应式设计详解 &#x1f4f1; 致读者&#xff1a;掌握响应式设计的艺术 &#x1f44b; 前端开发者们&#xff0c; 今天我们将深入探讨 CSS 响应式设计&#xff0c;学习如何创建适应各种设备的网页布局。 响应式基础 &#x1f680; 视口设…...

filecoin boost GraphQL API 查询

查询示例 查询失败交易 curl -X POST \ -H "Content-Type: application/json" \ -d {"query":"query { deals(limit: 10, query: \"failed to get size of imported\") { deals { ID CreatedAt Message } } }"} \ http://localhost:…...

SAS - Subtractive Port

在SAS&#xff08;串行连接SCSI&#xff0c;Serial Attached SCSI&#xff09;协议中&#xff0c;subtractive port 是一种特殊类型的端口&#xff0c;主要用于设备间的路由功能。它的作用是在路径选择过程中充当默认路径&#xff0c;以处理未明确指定路径的请求。以下是它的定…...

TCP客户端模拟链接websocket服务端

因一些特殊原因研究了下TCP模拟链接websocket。原理上可以连接但具体怎么连接怎么操作就不知道了&#xff0c;需要研究下&#xff0c;以下是个人研究的方案。 用线上和本地地址来做例子&#xff1a; 线上wss地址&#xff1a;wss://server.cs.com/cs/vido/1 本地地址ws://127…...

TypeScript 的崛起:全面解析与深度洞察

一、背景与起源 &#xff08;一&#xff09;JavaScript 的局限性 类型系统缺失 难以在编码阶段发现类型相关错误&#xff0c;导致运行时错误频发。例如&#xff0c;将字符串误当作数字进行数学运算&#xff0c;可能在运行时才暴露问题。函数参数类型不明确&#xff0c;容易传入…...

c#笔记2024

Ctrl r e自动添加get和set CompositeCurve3d 复合曲线 List<Entity> entS listline.Cast<Entity>().ToList();//list类型强转 前面拼上\u0003&#xff0c;就可以实现&#xff0c;不管有没有命令都能打断当前命令的效果 取消其他命令&#xff1a;Z.doc.SendStri…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...