暂无图片
暂无图片
暂无图片
暂无图片
1
暂无图片

springboot整合spring-data-elasticsearch3.x实操指南,文末附带源码

Elasticsearch之家 2022-07-16
4447

0. 引言

spring-data系列为众多中间件、数据库的操作提供了极其方便的API,对于elasticsearch也不例外,spring-data-elasticsearch不仅为我们提供了现成的CRUD接口,也提供了简便的各类java client的整合方案

所以今天我们就来讲解,如果在springboot项目中整合spring-data-elasticsearch

1. 环境介绍

在真正开始搭建之前,我们需要了解我们的运行环境,以防止大家因为环境的问题产生出各类不易排查的错误或冲突

首先要知道spring,spring-data-es,es之间的版本对应关系,我们可以在官网[1]中找到版本对应表


这里我使用的是


springboot与spring-data版本关系

一般来说我们引入spring-data-elasticsearch依赖的版本要与springboot版本保持对应,如上表所示,如果你的elasticsearch版本是7.15,那么对应的springboot版本就是2.6.x,spring-data-elasticsearch版本是4.3.x

这种对应版本时,我们可以通过引入spring-boot-starter-data-elasticsearch
依赖,spring-boot-starter依赖会自动根据我们的springboot版本匹配对应的spring-data-elasticsearch版本来引入,就不用我们再去查找版本表来手动声明版本了

比如我创建的项目springboot版本是2.3.7.RELEASE
,当我引入spring-boot-starter-data-elasticsearch
后,我们点击其pom文件会发现,其对应的spring-data-elasticsearch版本是4.0.6.RELEASE



这种方式是我们更加推荐的,但是实际开发时,会面临一些不如人愿的情形,比如我们是在旧项目中引入spring-data-elasticsearch,旧项目的springboot版本已经固定,不允许修改,但是我们使用的es版本比较新,导致springboot对应的spring-data-elasticsearch和es版本就不匹配了,这种时候,就需要我们根据需要手动声明spring-data-elasticsearch版本

同时还要注意,不同的spring-data-elasticsearch版本所支持的方法会有所调整,你可能会发现在网上搜到的一些方法,在你的环境用起来就报错或者达不到想要的效果,这就是版本差异导致的问题。这就需要我们去详细了解不同版本间API的调整

具体可以通过官网[2]查看,但更多的还需要我们自己实践出真知

2. 环境搭建

1、首先创建一个springboot项目,并且引入spring web
spring-data-elasticsearch
依赖

2、修改配置文件application.yml

这里需要注意,提前开启好es服务器的9200端口,否则会导致无法连接到es

3、创建索引实体类

这里的实体类也就是我们es索引中所对应的数据结构

比如我们要在es中创建的索引如下所示,注意这里使用了ik分词器,需要提前在es中安装,这里就不再演示安装了,不需要中文分词的可以不用安装

那么对应的实体类就如下所示,因为我这里演示用的es单节点,所以设置主分片数为1,副本分片为0,否则会导致节点状态报黄

其次还需要注意的是,这里声明了type="_doc"
,type属性在新版本中已经被取消了,默认为“_doc”,这里因为我使用的spring-data-elasticsearch版本还是3.2.x,这个版本中还需要声明type,否则会创建与类名同名的type。但因为es使用的是高版本的,已经默认创建了"_doc"的type,不声明的会就会创建两个type,导致启动报错。

声明后后续启动项目会出现[types removal] Using include_type_name in put mapping requests is deprecated. The parameter will be removed in the next major version
报错,不影响使用,但是大家要做了解

大家可以看到其属性是一一对应的。其中日期类型如果不声明format的话,默认是strict_date_optional_time||epoch_millis
,其类型说明可参考官方文档介绍[3]

当然这种实体类是比较简单的,一般我们使用es索引时都会有比较复杂的嵌套结构,比如索引中有子数据,即基础数组数据,或者json数组数据

所谓基础数组就是数组中承装的是基础类型,而json数组就是承装的是一个子类

在es索引中的定义为

那么到实体类中定义也类似,可以看到基础类型的数组直接申明为元素的数据类型即可,而json型数组是需要声明为Nested
类型的,这也是es的基础知识,这里就不做展开,大家了解即可

4、创建Repository
接口,实现简单的增删改查方法

spring-data-elasticsearch提供了ElasticsearchCrudRepository
接口,来让我们快速实现简单的增删改查方法,使用也很简单,只需要继承ElasticsearchCrudRepository
类即可,该类的第一个参数是我们的索引实体类,第二个参数是id字段数据类型

该接口提供了常见的增删改查方法,同时也支持我们自定义方法,可以通过如下两种方法定义一些简单的CRUD方法:

通过spring data自带的语法来自动生成衍生方法

如:根据名称来查询

支持的语法有



通过@Query自定义查询

query中的就是查询的DSL语句,?0
表示第一个参数

如果需要分页的话,也可以添加Pageable来实现分页

此外我们再添加几个不同类型的查询方法来方便测试:

5、创建controller

6、启动项目

如果这里启动失败的话,请检查下配置文件中填写的es地址是否正确,或者根据报错内容进行排错


7、调用save接口,新增数据测试




保存成功,在kibana中查询数据,发现也已经添加成功了

这里可以看到,新增数据的时候如果不声明id值的话,会默认给我们一个随机ID



8、调用查询接口

getByName



queryByName



getAllByName



pageAllByName



查询成功

这里可能会产生的一个错误是: NoSuchMethodError: org.elasticsearch.search.SearchHits.getTotalHits()

这是因为es7.x版本时要求springboot版本得是2.3.x。反之如果你的springboot版本是2.3.x那么spring-data-elasticsearch对应的版本得是4.0.x+。如我所用的spring-data-elasticsearch版本为3.2.12,则springboot版本不能是2.3+。可以结合上文的版本表对应版本

至此我们的基础环境就搭建成功了,但是要深入使用还需要以下额外配置

3. 配置RestHighLevelClient

上述提供的ElasticsearchCrudRepository
仅仅只能实现简单的CRUD,我们很多场景下是需要进行复杂的查询或聚合操作的

这个时候就需要使用其他的java client来补充操作了,比如HighLevelRestClient,不过大家要了解的是es官方已经不推荐使用Rest Client和Transport Client了,并且会在es8.x时废除。更加推荐使用Java Client,但是因为学习成本、使用习惯以及很多公司仍然在使用6.x或更早版本的es,所以在es7.x版本或更早,HighLevelRestClient依旧是不错的选择



要配置也很简单,只需要添加配置类

关于利用RestHighLevelClient
实现更加复杂的es查询、聚合操作,可以参考专栏的其他文章,这里就不再深入了。

4. 设置日期类型字段格式

如上所示的演示操作中,有一点不知道大家发现没有,我们在添加数据时,是没有添加日期类型的字段createDate
的。那么我们现在来添加试试看



结果出现报错,根据报错内容来看,是因为es默认的时间类型格式是yyyy-MM-dd'T'HH:mm:ss.SSSZ
,但我们更倾向于使用yyyy-MM-dd HH:mm:ss
的日期格式

那么我们要如何改变这个日期格式呢?

问题出在前端向后端接口传送日期数据时jackson无法转换,只需要在配置文件中申明

或者在对应字段上添加注解

新增数据,执行成功


日期类型数据的问题解决了,但是我们在kibana中查询数据发现,我们在实体类中设置了字段的大小写命名转换为下划线的,如实体类中createDate
映射到es中为create_date
,但实际并没有如我们所愿进行转换,这就是我们下一步需要继续配置的



5. 实体类映射配置

如上所示,实体类中的字段并没有对应上es索引中的字段。spring-data-es的字段映射是在EntityMapper
类中实现的

我们可以看到EntityMapper接口下有两个实现类,默认采用的是第一个,这个实现类中并没有识别@Field
注解,导致了没有对应上。



具体的源码分析,有兴趣的同学可以查看我另一篇博客:

Elastic实战:彻底解决spring-data-elasticsearch查询结果size大于0但显示为空问题[4]

我们只需要在ElasticRestClientConfig配置类中声明EntityMapper为ElasticsearchEntityMapper
即可

再次新增,数据正常



至此,我们的环境就搭建完成了,当然进阶使用还有更多的配置需要操作,我们将在后续进行讲解

回复‘springboot整合’获取文中项目源码!

Elastic  


~

References

[1]
 官网: https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#preface.requirements
[2]
 官网: https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#new-features
[3]
 官方文档介绍: https://www.elastic.co/guide/en/elasticsearch/reference/7.13/mapping-date-format.html
[4]
 Elastic实战:彻底解决spring-data-elasticsearch查询结果size大于0但显示为空问题: https://blog.csdn.net/qq_24950043/article/details/125010809

文章转载自Elasticsearch之家,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

街角雪
暂无图片
1年前
评论
暂无图片 0
springboot整合
1年前
暂无图片 点赞
评论