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
评论
