Spring Boot集成Elasticsearch(新手必看)
在没有 Spring Boot 之前,使用 Elasticsearch 非常痛苦,需要对 Elasticsearch 客户端进行一系列的封装等操作,使用复杂,配置烦琐。
所幸,Spring Boot 提供了对 Spring Data Elasticsearch 的封装组件 spring-boot-starter-data-elasticsearch,它让 Spring Boot 项目可以非常方便地去操作 Elasticsearch 中的数据。
值得注意的是,Elasticsearch 的 5.x、6.x、7.x 版本之间的差别还是很大的。Spring Data Elasticsearch、Spring Boot 与 Elasticsearch 之间有版本对应关系,不同的版本之间不兼容,Spring Boot 2.1 对应的是 Spring Data Elasticsearch 3.1.2 版本。对应关系如下表所示。
这是官方提供的版本对应关系,建议按照官方的版本对应关系进行选择,以避免不必要的麻烦。
目前,Spring 推荐使用 Elasticsearch 的方式,如下图所示:

图 2 Spring Boot操作Elasticsearch的方式
如上面的示例所示,通过 @Document 注解将数据实体对象与 Elasticsearch 中的文档和属性一一对应。
① @Document 注解会对实体中的所有属性建立索引:
② @Id 作用在成员变量,标记一个字段作为 id 主键。
③ @Field 作用在成员变量,标记为文档的字段,并指定字段映射属性:

图 3 数据保存的运行结果
结果表明索引数据保存成功,并且通过 id 能查询到保存的索引数据信息,说明在 Spring Boot 中成功集成 Elasticsearch。
所幸,Spring Boot 提供了对 Spring Data Elasticsearch 的封装组件 spring-boot-starter-data-elasticsearch,它让 Spring Boot 项目可以非常方便地去操作 Elasticsearch 中的数据。
值得注意的是,Elasticsearch 的 5.x、6.x、7.x 版本之间的差别还是很大的。Spring Data Elasticsearch、Spring Boot 与 Elasticsearch 之间有版本对应关系,不同的版本之间不兼容,Spring Boot 2.1 对应的是 Spring Data Elasticsearch 3.1.2 版本。对应关系如下表所示。
Spring Boot | Elasticsearch | Spring Data Elasticsearch |
---|---|---|
2.2.x | 6.8.4 | 3.2.x |
2.1.x | 3.1.x | 6.2.2 |
2.0.x | 3.0.x | 5.5.0 |
2.1.x | 1.5.x | 2.4.0 |
这是官方提供的版本对应关系,建议按照官方的版本对应关系进行选择,以避免不必要的麻烦。
Spring Boot操作Elasticsearch的方式
由于 Elasticsearch 和 Spring 之间存在版本兼容的问题,导致在 Spring Boot 项目中操作 Elasticsearch 的方式有很多种,如 Repositories、JestClient、Rest API 等。因此有必要梳理一下主流的 Spring Boot 操作 Elasticsearch 的方式。目前,Spring 推荐使用 Elasticsearch 的方式,如下图所示:

图 2 Spring Boot操作Elasticsearch的方式
- Repositories:继承自 Spring Data 中的 Repository 接口,所以支持以数据库的方式对数据进行增删改查的操作,而且支持已命名查询等数据查询。
- ElasticsearchRestTemplate:spring-data-elasticsearch 项目中的一个类,和其他 Spring 项目中的 Template 类似。ElasticsearchRestTemplate 是 Spring 对 ES 的 Rest API 进行的封装,支持复杂的数据查询、统计功能。
在Spring Boot项目中集成Elasticsearch
Spring Boot 提供的 spring-boot-starter-data-elasticsearch 组件为我们提供了非常便捷的数据检索功能。下面就来演示 Spring Boot 项目如何集成 Elasticsearch。1) 添加Elasticsearch依赖
首先在 pom.xml 中添加 spring-boot-starter-data-elasticsearch 组件依赖,代码如下:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
2) 配置Elasticsearch
在 application.properties 项目配置文件中添加 Elasticsearch 服务器的地址,代码如下:spring.elasticsearch.rest.uris=http://10.2.1.231:9200主要用来配置 Elasticsearch 服务地址,多个地址用逗号分隔。需要注意的是,Spring Data Elasticsearch 各版本的配置属性可能不一样。本示例中使用的是 7.6.2 版本。
3) 创建文档对象
创建实体对象类 Book,然后使用 @Document 注解定义文档对象,示例代码如下:@Document( indexName = "book" , replicas = 0) public class Book { @Id private Long id; @Field(analyzer = "ik_max_word",type = FieldType.Text) private String bookName; @Field(type = FieldType.Keyword) private String author; private float price; private int page; @Field(type = FieldType.Keyword, fielddata = true) private String category; // 省略get、set方法 public Book(){ } public Book(Long id,String bookName, String author,float price,int page,String category) { this.id = id; this.bookName = bookName; this.author = author; this.price = price; this.page = page; this.category = category; } @Override public String toString() { final StringBuilder sb = new StringBuilder( "{\"Book\":{" ); sb.append( "\"id\":" ) .append( id ); sb.append( ",\"bookName\":\"" ) .append( bookName ).append( '\"' ); sb.append( ",\"page\":\"" ) .append( page ).append( '\"' ); sb.append( ",\"price\":\"" ) .append( price ).append( '\"' ); sb.append( ",\"category\":\"" ) .append( category ).append( '\"' ); sb.append( ",\"author\":\"" ) .append( author ).append( '\"' ); sb.append( "}}" ); return sb.toString(); } }
如上面的示例所示,通过 @Document 注解将数据实体对象与 Elasticsearch 中的文档和属性一一对应。
① @Document 注解会对实体中的所有属性建立索引:
- indexName = "customer":表示创建一个名为 customer 的索引。
- type="customer":表示在索引中创建一个名为 customer 的类别,而在 Elasticsearch 7.x 版本中取消了类别的概念。
- shards = 1:表示只使用一个分片,默认为 5。
- replicas = 0:表示副本数量,默认为 1,0 表示不使用副本。
- refreshInterval = "-1":表示禁止索引刷新。
② @Id 作用在成员变量,标记一个字段作为 id 主键。
③ @Field 作用在成员变量,标记为文档的字段,并指定字段映射属性:
- type:字段类型,取值是枚举:FieldType。
- index:是否索引,布尔类型,默认是 true。
- store:是否存储,布尔类型,默认是 false。
- analyzer:分词器名称是 ik_max_word。
4) 创建操作的Repository
创建 CustomerRepository 接口并继承 ElasticsearchRepository,新增两个简单的自定义查询方法。示例代码如下:public interface BookRepository extends ElasticsearchRepository<Book, Integer>{ List<Book> findByBookNameLike(String bookName); }通过上面的示例代码,我们发现其使用方式和 JPA 的语法是一样的。
5) 验证测试
首先创建 BookRepositoryTest 单元测试类,在类中注入 BookRepository,最后添加一个数据插入测试方法。@Test public void testSave() { Book book = new Book(); book.setId(1); book.setBookName("西游记"); book.setAuthor("吴承恩"); repository.save(book); Book newbook=repository.findById(1).orElse(null); System.out.println(newbook); }单击 Run Test 或在方法上右击,选择 Run 'testSave',运行单元测试方法,查看索引数据是否插入成功,运行结果如下图所示:

图 3 数据保存的运行结果
结果表明索引数据保存成功,并且通过 id 能查询到保存的索引数据信息,说明在 Spring Boot 中成功集成 Elasticsearch。