本章开始学习springboot整合ElasticSearch 7.X版本并通过小demo实现基本的增删改查。实现如下案例:

1、当向数据新增一个商品信息时,同时向rabbitMQ发起消息(异步实现),让监听到消息的类去向ElasticSearch 也新增这个商品信息。

2、当去修改数据库的商品信息时,同时向rabbitMQ发起消息(异步实现),让监听到消息的类去向ElasticSearch 也去修改这个商品信息。

3、当删除数据库的商品信息时,同时也向rabbitMQ发起消息(异步实现),让监听到消息的类去向ElasticSearch 也去删除这个商品信息。

4、实现ElasticSearch的条件查询

5、实现ElasticSearch的分页查询

6、实现ElasticSearch的条件+分页查询。

7、实现ElasticSearch的高亮显示与查询条件相符合的值。

8、实现ElasticSearch的高亮显示与查询条件相符合的值并分页排序

最终效果:

qq交流群导航——>231378628


注意: 本章整合的ElasticSearch下载的客户端是windows版本,然后现在时间是2022.3.31。

Past Releases of Elastic Stack Software | ElasticLooking for a past release of Elasticsearch, Logstash, Kibana, es-hadoop, Shield, Marvel, or our language clients? You're in the right place.https://www.elastic.co/cn/downloads/past-releases#elasticsearch

官网提供的最新最新版本是8.1.1。最新版的使用跟以前7.X版本的完全不同,网上学习资料太少了,不得不降低版本学习7.X,本章节的学习下载的是elasticsearch-7.3.2,尝试了8.1.1的学习,问题实在是太多了,能力卑微,先不强求自己了。

注意:客户端下载的什么版本最好别去下最新版本,太难搞了。

!!!!提醒:本教程只适合elasticsearch-7.X版本,高版本不支持。

学习路线:


一、下载安装elasticsearch-7.3.2

二、下载安装elasticsearch图像化插件(elasticsearch-head-master)

三、建立父子工程

四、准备工作

五、实现ElasticSearch 新增商品信息

六、实现ElasticSearch 修改商品信息

七、实现ElasticSearch 删除商品信息

八、实现ElasticSearch 条件查询商品信息

九、实现ElasticSearch 分页查询商品信息

十、实现ElasticSearch 条件+分页查询商品信息

十一、实现ElasticSearch 高亮显示与查询条件相符合的值

十二、实现ElasticSearch的高亮显示与查询条件相符合的值并分页和排序


一、下载安装elasticsearch-7.3.2

Past Releases of Elastic Stack Software | ElasticLooking for a past release of Elasticsearch, Logstash, Kibana, es-hadoop, Shield, Marvel, or our language clients? You're in the right place.https://www.elastic.co/cn/downloads/past-releases#elasticsearch

下载本章节所用版本:

安装教程,转载自:windows环境下elasticsearch安装教程(超详细) - hualess - 博客园 (cnblogs.com)https://www.cnblogs.com/hualess/p/11540477.html


二、下载安装elasticsearch图像化插件(elasticsearch-head-master)

安装完成elasticsearch之后,需要安装一个插件去图形化操作elasticsearch,教程上讲的需要先下载node,然后用node自带的npm下载grunt,随后去修改一下elasticsearch的配置文件即可通过9100端口访问图形界面,教程如下:

windows环境下elasticsearch安装教程(超详细) - hualess - 博客园 (cnblogs.com)https://www.cnblogs.com/hualess/p/11540477.html

执行命令运行head插件。

ES双击elasticsearch-7.3.2\bin目录下的elasticsearch.bat即可。

启动后长这个样子(启动时若会提示需要密码,这时需要去修改elasticsearch的配置文件)。


三、建立父子工程

为了测试上述功能,先建立一个父子工程,在学习RabbitMQ和KafKa时都有建过,直接拿来使用,如下:


四、准备工作

在开始之前,先做好准备工作,如下:

  • 构建好父子模块的关系
  • 在父工程引入所需依赖
  • 修改provider和consumer的配置文件
  • 创建mysql表
  • 安装rabbitMQ(默认已经安装好,前面章节有安装过)
  • 在common工程创建好公共模块

1、构建好父子模块的关系:

此处不讲了,在前面的章节有讲过。

2、在父工程引入所需依赖

此次学习需要用到mybatis-plus和rabbitMQ和elasticsearch,所有依赖情况如下:

我的springboot版本是:2.6.4,其他依赖不加版本会根据springboot版本去自动匹配版本导入。

3、provider的配置文件

4、consumer的配置文件

两者配置文件差不多,主要就是连接rabbitmq和elasticsearch,上图main:allow-bean-definition-overriding: true是我在测试时的一个报错,根据报错的一个bean的重复解决方案。

        注意:版本不一样,连接elasticsearch的写法不一样,高版本好像最基本的配置不需要了。

5、mysql表如下:

6、common模块代码如下:

        此处我的这个实体类有两个用处:

  • 用于作为mybatis-plus的实体类(TableName注解映射mysql表名、TableField注解映射mysql字段)
  • 用于作为elasticsearch的实体类(Document注解标记该实体类属于的索引和类型,类型默认是_doc类型,索引就相当于数据库的表名吧,若elasticsearch中不存在这个索引,会根据这个索引去创建一个、Field注解指定这个字段在elasticsearch是数值类型,但是在后面根据该字段排序时会使用。)
  • 此处采用序列化是因为在rabbitmq传输该实体类对象时,若不序列化传输会报错。

7、在消费者模块准备rabbitMQ的绑定配置类

@Configuration
public class TopicElasticSearchConfig {@Beanpublic TopicExchange saveExchange() {return new TopicExchange("es_save_exchange", true, false);}@Beanpublic TopicExchange deleteExchange() {return new TopicExchange("es_delete_exchange", true, false);}@Beanpublic Queue esSaveQueue() {return new Queue("es.save.queue", true);}@Beanpublic Queue esDeleteQueue() {return new Queue("es.delete.queue", true);}@Beanpublic Binding esSaveBinding() {return BindingBuilder.bind(esSaveQueue()).to(saveExchange()).with("es");}@Beanpublic Binding esDeleteBinding() {return BindingBuilder.bind(esDeleteQueue()).to(deleteExchange()).with("es");}}

建立一个接收修改和新增消息的交换机(因为对于elasticsearch来说,新增和修改方法一样),再建立一个接收删除消息的交换机,建立两个队列和绑定,如上图。

8、建立消费端的监听器

        监听上面建立的两个队列。

9、建立mybatis-plus所需要的mapper层

10、建立测试用controller

准备工作完成。


五、实现ElasticSearch 新增商品信息

要实现向mysql数据库新增数据的同时通过rabbitMQ接收消息然后向elasticsearch也插入数据,所以实现如下:

先在controller编写新增接口

        向数据库新增数据,同时向rabbitmq发送新增的消息。

然后再新增消息队列监听器编写向elasticsearch新增数据的逻辑。

        操作elasticsearch是通过继承Repository接口完成的,在消费者服务和生产者服务都新增如下类

里面自定义的方法是后面所用到的,继承ElasticsearchRepository接口后默认提供了最基本的增删改查操作,类似Mybatis-plus的BaseMapper。

ElasticsearchRepository可以直接调用save方法进行报错。

结果如下:

同步保存成功。


六、实现ElasticSearch 修改商品信息

elasticsearch的修改操作也是调用Repository的save方法,若传入的id已存在则是执行修改,若传入的id不存在,则是新增。代码如下:

同样在controller里加上修改接口,然后向数据修改,然后发送消息到MQ,然后再MQ的队列监听器进行处理。

        还是上面的新增逻辑,原因已经讲了。

查看效果:

        这是原来的数据。

        调用接口后,这是现在的数据

修改成功。


七、实现ElasticSearch 删除商品信息

删除跟新增修改差不多,代码如下:

controller新增删除接口。

在删除队列监听器处理elasticsearch的删除方法。

测试结果删除成功。


八、实现ElasticSearch 条件查询商品信息

后面就只针对provider服务实现了,不通过MQ了。

基本的增删改完了,然后一步一步的实现各种查询操作,指令实现基本的条件查询,如下。

新增条件查询测试接口。

根据name和content模糊查询,采用自定义查询语句的方式实现,这里要注意Repository的写法。

根据什么查询就写findBy什么然后加字段名And或者Or之类的,然后写下一个字段名,这里只学习了最基本的使用,详细的就不展开了,后面再面向百度学习,然后方法传入的参数会根据参数位置一一匹配方法名前面写的字段名,Repository会自动生成查询语句。

测试结果如下:

条件查询成功。


九、实现ElasticSearch 分页查询商品信息

然后实现一下分页查询,需要用到Pageable类,提供分页参数,Repository的方法支持这个类来查询,代码如下:

依旧新增一个测试接口。

测试结果:

测试成功。注意:Pageable默认的入参是第0页,按每页20条查询。网上有说默认是(0,10),可能是该类的版本不同,我用的版本是默认0,20。对于elasticsearch来说是先从0开始的。还要注意传参是page和size,别写错了。返回的Page数据结构如下:


十、实现ElasticSearch 条件+分页查询商品信息

当完成了分页查询和条件查询,下面写一个接口同时满足上面两个,代码如下。

新增一个测试接口,然后同时传入查询条件和分页参数,重载一个刚才的方法,修改入参和返回值。

测试结果如下。

测试成功。


十一、实现ElasticSearch 高亮显示与查询条件相符合的值

下面简单实现一个elasticsearch的特色,高亮显示。当我们在百度搜索时,例如搜索牛批。

它能够高亮显示搜索到的信息中所匹配的值,下面通过elasticsearch简单实现一下,代码如下。

//高亮显示@CrossOrigin@GetMapping("getLightShopList")public List<Shop> getLightShopList(@RequestParam(required = false) String name) {//构建查询条件,只要name或者content其中一个满足传入的name的查询条件即可
//        QueryBuilder queryBuilder1 = new MatchQueryBuilder("name", name);
//        QueryBuilder queryBuilder2 = new MatchQueryBuilder("content", name);//上面这样写只能用到最后一个,要下面这样写,组合查询QueryBuilder queryBuilder = QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("name", name)).should(QueryBuilders.matchQuery("content", name));//查询NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder)//添加高亮显示字段.withHighlightFields(new HighlightBuilder.Field("name"), new HighlightBuilder.Field("content"))//自定义高亮显示颜色.withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:yellow'>").postTags("</span>")).build();//开始查询SearchHits<Shop> search = elasticsearchRestTemplate.search(searchQuery, Shop.class);//得到查询返回的内容List<SearchHit<Shop>> searchHits = search.getSearchHits();//设置一个最后需要返回的实体类集合List<Shop> shops = new ArrayList<>();//遍历返回的内容进行处理for (SearchHit<Shop> searchHit : searchHits) {//高亮的内容Map<String, List<String>> highlightFields = searchHit.getHighlightFields();//将高亮的内容填充到content中searchHit.getContent().setName(highlightFields.get("name") == null ? searchHit.getContent().getName() : highlightFields.get("name").get(0));searchHit.getContent().setContent(highlightFields.get("content") == null ? searchHit.getContent().getContent() : highlightFields.get("content").get(0));//放到实体类中shops.add(searchHit.getContent());}return shops;}

上面的例子都是通过Repository提供的APi方法实现的,高亮显示通过它加上注解好像也可以实现,上面的方法是引入elasticsearchRestTemplate来实现的。

  • 先构建查询条件,通过第二种方式实现,第一种方式创建两个对象,在使用时第二个会覆盖第一个。
  • 整合查询条件以及高亮显示设置,自定义需要高亮显示的字段,并自定义高亮显示的字段的颜色。
  • 调用方法查询,并将返回的数据重新封装。

测试结果如下:

name和content字段中,相匹配的就会查询出来并高亮显示。具体的匹配规则和优先级都是可以设置的。


十二、实现ElasticSearch的高亮显示与查询条件相符合的值并分页和排序

完成了最基本的高亮显示,最后再同时整点分页和排序。

代码如下。

//高亮显示+分页+条件+排序@CrossOrigin@GetMapping("getLightShopByPageList")public Map getLightShopByPageList(@RequestParam(required = false) String name,Pageable pageable) {//组合查询QueryBuilder queryBuilder = QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("name", name)).should(QueryBuilders.matchQuery("content", name));//构建排序,如果实体类上该字段没有加type,这里排序字段上面要加keyword,不然会报错。
//        FieldSortBuilder priceSortBuilder = SortBuilders.fieldSort("price.keyword").order(SortOrder.ASC);FieldSortBuilder priceSortBuilder = SortBuilders.fieldSort("price").order(SortOrder.ASC);//查询NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder)//添加高亮显示字段.withHighlightFields(new HighlightBuilder.Field("name"), new HighlightBuilder.Field("content"))//自定义高亮显示颜色.withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:yellow'>").postTags("</span>")).withPageable(pageable).withSorts(priceSortBuilder).build();//开始查询SearchHits<Shop> search = elasticsearchRestTemplate.search(searchQuery, Shop.class);//得到查询返回的内容List<SearchHit<Shop>> searchHits = search.getSearchHits();//设置一个最后需要返回的实体类集合List<Shop> shops = new ArrayList<>();//遍历返回的内容进行处理for (SearchHit<Shop> searchHit : searchHits) {//高亮的内容Map<String, List<String>> highlightFields = searchHit.getHighlightFields();//将高亮的内容填充到content中searchHit.getContent().setName(highlightFields.get("name") == null ? searchHit.getContent().getName() : highlightFields.get("name").get(0));searchHit.getContent().setContent(highlightFields.get("content") == null ? searchHit.getContent().getContent() : highlightFields.get("content").get(0));//放到实体类中shops.add(searchHit.getContent());}Map map = new HashMap();map.put("currentPageSIze",pageable.getPageSize());map.put("currentNumber",pageable.getPageNumber());map.put("content",shops);return map;}

对比上一个就是增加了排序和分页,所有直接在上面改动了。

  • 通过FieldSortBuilder构建一个排序Builder通过withSorts方法加入到NativeSearchQuery中。
  • 新增传入对象Pageable,再通过withPageable方法加入到NativeSearchQuery。
  • 封装一下。

注意:排序时,若实体类上price字段没加@Field(type = FieldType.Integer), 查询会报错,在查询时查询字段必须写成price.keyword,否则就必须在实体类上加@Field注解,不然请求接口测试会报elasticsearch的错。若一个分区的数据(不设置默认在一个分区),若存在price数据不是同种类型,排序也会失效,不知道对不对,反正我测试时遇到了这个问题,后面测试时把前面该索引(shop)直接删了重新来过的(为了保证price类型一致)。

测试结果如下。

若修改成SortOrder.DESC。

查看排序成功。

  (2022.4.3新增)上面是通过elasticsearchRestTemplate的方法实现的,下面简单使用注解方式实现一下:

修改Repository类:

仍然借助Repository自动给我们生成查询语句,不同的是,我们自定义高亮显示字段,配合Highlight注解、HighlightField注解、HighlightParameters注解实现。

  1. Highlight:设置高亮显示参数。
  2. HighlightField:注明哪些参数需要高亮显示。
  3. HighlightParameters:自定义高亮的样式参数设置,类似elasticsearchRestTemplate里面的HighlightBuilder。

controller层新增测试接口:

然后写了一个简单的前端界面进行测试。

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title></head><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script><body><div class="row" style="margin-left: 30%;margin-top: 30px;"><div class="col-lg-6"><div class="input-group"><div class="input-group-prepend"><span class="input-group-text " id="basic-addon1">名称</span></div><input type="text" class="form-control name" placeholder="搜索"><div class="input-group-prepend" style="margin-left: 20px;"><span class="input-group-text " id="basic-addon1">内容</span></div><input type="text" class="form-control content" placeholder="搜索"><span class="input-group-btn"><button class="btn btn-primary" type="button" onclick="fun1()">搜索</button></span></div><!-- /input-group --></div><!-- /.col-lg-6 --></div><!-- /.row --><div class="neirong" style="width: 100%;height: 500px;background-color: aliceblue;display: flex;justify-content: center;"></div></body><script>function fun1(){console.log("点击");$.ajax({url:"http://localhost:7778/shopController/hightLightShow2",data:{"page":"0","size":"10","name":$(".name").val(),"content":$(".content").val()},type:"get",dataType: "json",success: function(data) { $(".neirong").html('');console.log(data);var html="";for(var i=0;i<data.length;i++){name = data[i].highlightFields.name==undefined?data[i].content.name:data[i].highlightFields.namecontent = data[i].highlightFields.content==undefined?data[i].content.content:data[i].highlightFields.contenthtml = html+`<div class="card" style="width: 18rem;height:18rem;margin-right:10px"><div class="card-body"><h5 class="card-title">`+name+`</h5><p class="card-text">`+content+`</p><a href="#" class="btn btn-primary">购买</a></div></div>`}$(".neirong").append(html);}});}</script>
</html>

最终效果就是下图这个样子:

后面继续学习elasticsearch。

【十九】springboot整合ElasticSearch实战(万字篇)相关推荐

  1. Springboot 整合ElasticSearch(Client篇)

    目录 1.简介 2.依赖.pom.xml 3.配置类ESConfig 4.yml配置文件 5.实体类,省略不写了,根据自己的业务定义实体类 6.Client的使用 7.有问题留言,谢谢 1.简介 相信 ...

  2. java-web系列(九)---SpringBoot整合ElasticSearch

    前言 这个项目的github地址:extensible项目的github地址 extensible项目当前功能模块如下: java-web系列(一)-搭建一个基于SSM框架的java-web项目 ja ...

  3. es springboot 不设置id_原创 | 一篇解决Springboot 整合 Elasticsearch

    ElasticSearch 结合业务的场景,在目前的商品体系需要构建搜索服务,主要是为了提供用户更丰富的检索场景以及高速,实时及性能稳定的搜索服务. ElasticSearch是一个基于Lucene的 ...

  4. 【数据篇】SpringBoot 整合 Elasticsearch 实践数据搜索引擎

    写在最前 Elasticsearch 入门必读 Docker安装ELK Spring Data Elasticsearch 参考文档 版本选择 Spring Data Release Train Sp ...

  5. Spring Boot(九):整合elasticsearch并使用logstash同步数据

    一到周末,就想在家里躺尸,逛逛B站,看看直播,打打游戏,美哉美哉.当然,作为一名有自我修养的程序员,学习也是必不可少的.前段时间,我司的另一个项目组接手的项目中用到了elasticsearch,我就查 ...

  6. SpringBoot整合ElasticSearch实现多版本的兼容

    前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和Spring ...

  7. SpringBoot整合Elasticsearch详细步骤以及代码示例(附源码)

    准备工作# 环境准备# JAVA版本 Copy java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1. ...

  8. Springboot 整合ElasticSearch 常用的插入查询,模糊查询,范围查询

    前言 本来该篇教程就应该写到 Springboot 整合 ElasticSearch 入门教学必看 https://blog.csdn.net/qq_35387940/article/details/ ...

  9. Springboot 整合 ElasticSearch 入门教学必看

    ElasticSearch 相比搜到这篇文章的人,都已经有过对它的了解, 一种流行的企业级搜索引擎,是一个分布式,高性能.高可用.可伸缩的搜索和分析系统. 那么用我粗俗的言语来说,它就是提供一个存储数 ...

最新文章

  1. 开放下载!《阿里巴巴大数据及AI实战》深度解析典型场景大数据实践
  2. Ext.Net学习笔记18:Ext.Net 可编辑的GridPanel
  3. Github 1.3万星,迅猛发展的JAX对比TensorFlow、PyTorch
  4. Linux多线程编程(一)---多线程基本编程
  5. Axure - 破解
  6. 电脑用linux命令大全,电脑操作时常用的一些Linux命令
  7. js中for循环调用回调函数,一直循环最后一个
  8. PowerPC 汇编
  9. python读取excel数据生成word_利用Python将excel数据读取到word表格
  10. CentOS6.7 Linux Squid 代理服务器安装配置
  11. ArcMap基本操作
  12. GPS测量误差来源分析
  13. 摄影测量后方交会算法C#实现
  14. c# 时间戳的使用,日期判定(时间戳获取、 时间戳和DateTime的转换、时差计算)
  15. 写一个京东最顶部的导航条
  16. Linux——万字总结用户与组相关知识!建议收藏!
  17. 区块链原理和fabric概念介绍
  18. springboot环境配置,yml格式,不同环境切换
  19. Vmware虚拟机ip为127.0.0.1的解决办法,修改虚拟机IP的详细步骤
  20. java版我的世界游侠怎么联机_我的世界如何联机手机版

热门文章

  1. TMR磁传感器应用笔记|安防报警篇
  2. 从一个APK调用另一个APK的方法
  3. 什么软件可以测试电路板,在线测试仪的功能及在电路板维修中的应用
  4. JS中使用FormData上传文件、图片的方法
  5. 庄子 内篇 人间世第四
  6. 智能运维(AIOps)系列之一:个人对智能运维的理解
  7. 腾讯第一次种黄瓜,又长又直,还拿了奖
  8. 【SDC】揭开无人驾驶的神秘面纱
  9. sql 删除所有外键约束,表,存储过程,试图
  10. 物体间的粘度是由什么决定的?