使用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文件,并导入MySQL数据库中2. 利用Logstah完成MySQL到ES的数据同步3. 开始编写功能接口3.1 全文检索接口3.2 查询详情 4. 前端调用 全文检索 任务描述 在获取到数据之后如何在ES中进行数据建模&a…...
通过k-means对相似度较高的语句进行分类
本文介绍了如何使用K-Means算法对相似度较高的语句进行分类,并附上java案例代码 import java.util.ArrayList; import java.util.List; import java.util.Random;public class KMeansTextClustering {public static void main(String[] args) {// 初始化语句数据集…...
国信华源科技赋能长江蓄滞洪区水闸管护项目验收成果报道
“碧水悠悠绕古城,闸启长江万象新。”近日,由北京国信华源科技有限公司倾力打造的万里长江蓄滞洪区水闸管护项目,圆满通过验收,为这片鱼米之乡的防洪安全注入了新的科技活力。 长江之畔,水闸挺立,犹如干堤上…...
HTML:表格重点
用表格就用table caption为该表上部信息,用来说明表的作用 thead为表头主要信息,效果加粗 tbody为表格中的主体内容 tr是 table row 表格的行 td是table data th是table heading表格标题 ,一般表格第一行的数据都是table heading...
wine的使用方法
wine版本 所有分支,新的主要版本: wine-x.0 All branches, release candidates:各分支、候选版本: wine-x.0-rcn Stable branch updates: 稳定分支更新: 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. 下载对应的离线包 地址:http://www.rpmfind.net/linux/rpm2html/search.php?query&submitSearch 例…...
Excel拆分脚本
Excel拆分 工作表按行拆分为工作薄 工作表按行拆分为工作薄 打开要拆分的Excel文件,使用快捷键(AltF11)打开脚本界面,选择要拆分的sheet,打开Module,在Module中输入脚本代码,然后运行脚本 Su…...
Mybatis---事务
目录 引入 一、事务存在的意义 1.事务是什么? 2.Mybatis关于事务的管理 程序员自己控制处理的提交和回滚 引入 一、事务存在的意义 1.事务是什么? 多个操作同时进行,那么同时成功,那么同时失败。这就是事务。 事务有四个特性…...
企业直播间媒体分发新闻转播拉流推广名单(金融财经科技类)
【本篇由 言同数字媒体直播分发 原创】随着直播与短视频成为各大企业营销的重要手段,如何选择合适的视频平台进行内容分发与拉流成为了企业关注的焦点。对于财经和科技类企业而言,选择具有专业受众群体和广泛传播能力的平台尤为重要。下面是一些可以帮助…...
华为FreeBuds Pro 4丢了如何找回?(附查找功能使用方法)
华为FreeBuds Pro 4查找到底怎么用?华为FreeBuds Pro 4有星闪精确查找和离线查找,离线查找功能涵盖播放铃声、导航定位、星闪精确查找、上线通知、丢失模式、遗落提醒等。星闪精确查找是离线查找的子功能,当前仅华为FreeBuds Pro 4充电盒支持…...
若依微服务登录密码加密传输解决方案
文章目录 一、需求提出二、应用场景三、解决思路四、注意事项五、完整代码第一步:前端对密码进行加密第二步:后端工具类实现 RSA 加解密功能第三步:登录接口中添加解密逻辑 六、运行结果总结 一、需求提出 在默认情况下,RuoYi 微…...
NVR小程序接入平台/设备EasyNVR深度解析H.265与H.264编码视频接入的区别
随着科技的飞速发展和社会的不断进步,视频压缩编码技术已经成为视频传输和存储中不可或缺的一部分。在众多编码标准中,H.265和H.264是最为重要的两种。今天我们来将深入分析H.265与H.264编码的区别。 一、H.265与H.264编码的区别 1、比特率与分辨率 H.…...
Redisson常用方法
Redisson 参考: 原文链接 定义:Redisson 是一个用于与 Redis 进行交互的 Java 客户端库 优点:很多 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)-- 响应式设计详解
前端技术探索系列:CSS 响应式设计详解 📱 致读者:掌握响应式设计的艺术 👋 前端开发者们, 今天我们将深入探讨 CSS 响应式设计,学习如何创建适应各种设备的网页布局。 响应式基础 🚀 视口设…...
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(串行连接SCSI,Serial Attached SCSI)协议中,subtractive port 是一种特殊类型的端口,主要用于设备间的路由功能。它的作用是在路径选择过程中充当默认路径,以处理未明确指定路径的请求。以下是它的定…...
TCP客户端模拟链接websocket服务端
因一些特殊原因研究了下TCP模拟链接websocket。原理上可以连接但具体怎么连接怎么操作就不知道了,需要研究下,以下是个人研究的方案。 用线上和本地地址来做例子: 线上wss地址:wss://server.cs.com/cs/vido/1 本地地址ws://127…...
TypeScript 的崛起:全面解析与深度洞察
一、背景与起源 (一)JavaScript 的局限性 类型系统缺失 难以在编码阶段发现类型相关错误,导致运行时错误频发。例如,将字符串误当作数字进行数学运算,可能在运行时才暴露问题。函数参数类型不明确,容易传入…...
c#笔记2024
Ctrl r e自动添加get和set CompositeCurve3d 复合曲线 List<Entity> entS listline.Cast<Entity>().ToList();//list类型强转 前面拼上\u0003,就可以实现,不管有没有命令都能打断当前命令的效果 取消其他命令:Z.doc.SendStri…...
Hadoop一课一得
Hadoop作为大数据时代的奠基技术之一,自问世以来就深刻改变了海量数据存储与处理的方式。本文将带您深入了解Hadoop,从其起源、核心架构、关键组件,到典型应用场景,并结合代码示例和图示,帮助您更好地掌握Hadoop的实战…...
AI生成图表化:深入探索Mermaid
引言 在使用生成式AI时,只要你提出让AI帮你生成mermaid图,AI的生成就会出现丰富的图形! 在现代文档编写中,图表的使用不仅能增强文档的可读性,还能更直观地表达复杂的概念和流程。Mermaid 作为一款开源的图表绘制工具…...
25.DDD数量关系
学习视频来源:DDD独家秘籍视频合集 https://space.bilibili.com/24690212/channel/collectiondetail?sid1940048&ctype0 文章目录 关系型数据库的数量关系领域模型的数量关系实现聚合数量关系聚合内聚合间具体说明代码 数量关系是本质吗?领域对象之…...
Linux应用开发————线程池
线程池 定义:简单来说,就是存放多个线程的池子。当创建线程池时,就给池中存放一些线程,如果有任务要执行,就从池中取出一个线程执行任务,依次类推;当所有线程都在执行任务时,其他任务…...
Spring Boot 集成阿里云OSS 完成文件上传下载
前言: 文件上传下载在项目开发中是一个非常常见的业务场景,在云服务上还没有兴起的时候,一般来说都会把文件单独存放到文件服务器上,随着云服务的兴起,各类云服务厂商都提供了 OSS 服务,本篇我们分享 Spri…...
使用ERA5数据绘制风向玫瑰图的简易流程
使用ERA5数据绘制风向玫瑰图的简易流程 今天需要做一个2017年-2023年的平均风向的统计,做一个风向玫瑰图,想到的还是高分辨率的ERA5land的数据(0.1分辨率,逐小时分辨率,1950年至今)。 风向,我分为了16个&…...
测试脚本并发多进程:pytest-xdist用法
参考:https://www.cnblogs.com/poloyy/p/12694861.html pytest-xdist详解: https://www.cnblogs.com/poloyy/p/14708825.html 总 https://www.cnblogs.com/poloyy/category/1690628.html...
数据可视化的Python实现
一、GDELT介绍 GDELT ( www.gdeltproject.org ) 每时每刻监控着每个国家的几乎每个角落的 100 多种语言的新闻媒体 -- 印刷的、广播的和web 形式的,识别人员、位置、组织、数量、主题、数据源、情绪、报价、图片和每秒都在推动全球社会的事件,GDELT 为全…...
【Linux系列】Linux 系统配置文件详解:`/etc/profile`、`~/.bashrc` 和 `~/.bash_profile`
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
uni-app实现小程序、H5图片轮播预览、双指缩放、双击放大、单击还原、滑动切换功能
前言 这次的标题有点长,主要是想要表述的功能点有点多; 简单做一下需求描述 产品要求在商品详情页的头部轮播图部分,可以单击预览大图,同时在预览界面可以双指放大缩小图片并且可以移动查看图片,双击放大࿰…...
业务员自己掏钱做网站可以吗/网络营销这个专业怎么样
修改jquery validatebox为英文校验提示为中文提示 by:授客 QQ:1033553122 测试环境 jquery-easyui-1.5.3 问题描述: 如图,想把校验提示由英文改成中文 解决方案 编辑jquery.easyui.min.js 文件,搜索以下内容, missingM…...
做电影网站失败/百度在线提问
前言在实际项目中常会遇到许多功能相似的类,这时我们只有正确的理解了重载和重写的用法才能设计出清晰而简洁的类,可以说重写和重载在编写代码过程中的作用非同一般。本文也将着重介绍两者的区别以及应用场景。区别1.override 覆写(重写)重写发生在子类继…...
潍坊设计网站建设/网页制作软件dw
问题:read_csv()读取csv文件后,dataframe数据表只有一列。CSV原文件样例,包含3列 代码: import pandas as pd df pd.read_csv(D:\数据源字段列表.csv, encodingutf-8) #包含中文路径名和文件名 运行后报错:OSError: I…...
百度推广 个人网站/模板建站和开发网站区别
链表相关问题在面试中出现的频率非常高。以下是我在前段时间学习《剑指offer》过程中对链表问题的总结。 单链表的创建和遍历 求单链表中节点的个数 查找单链表中的倒数第k个结点 查找单链表中的中间结点反转链表从尾到头打印单链表删除链表结点 1. 单链表的创建和遍历 /** …...
怒江商城网站建设/在线bt磁力搜索
目录 全局组件局部组件组件的嵌套(父子组件)子组件向父组件传数据(子父同步)子组件修改父组件数据componet & v-bind:isslot组件之间进行数据发送什么是组件? 组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素&#x…...
哈尔滨网站域名备案/北京千锋教育培训机构怎么样
在优化智能客服时,添加泛化语料是最麻烦也是最必要的一个环节,意图的泛化得越好,机器人就看起来就越智能,根据之前的工作经验,我整理了一下思路,给大家介绍三个语法泛化能力的方案。 一、短期(单个词泛化…...