前面介紹了Elasticsearch的特點和優勢,接下來在Spring Boot項目中使用Elasticsearch一步一步地實作搜尋引擎的功能。
一、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版本。對應關系如表13-1所示。
表13-1 Spring Data Elasticsearch、Spring Boot與Elasticsearch的對應關系
Spring Data Elasticsearch | Spring Boot | Elasticsearch |
3.2.x | 2.2.x | 6.8.4 |
3.1.x | 2.1.x | 6.2.2 |
3.0.x | 2.0.x | 5.5.0 |
1.5.x | 2.4.0 |
這是官方提供的版本對應關系,建議按照官方的版本對應關系進行選擇,以避免不必要的麻煩。
二、Spring Boot操作Elasticsearch的方式
由于Elasticsearch和Spring之間存在版本相容的問題,導緻在Spring Boot項目中操作Elasticsearch的方式有很多種,如Repositories、JestClient、Rest API等。是以有必要梳理一下主流的Spring Boot操作Elasticsearch的方式。目前,Spring推薦使用Elasticsearch的方式,如下圖所示:

我們看到Spring Boot提供了ElasticSearchRepository和ElasticsearchRestTemplate實作索引資料的增删改查。
- ElasticSearchRepository:繼承自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中的文檔和屬性一一對應。
(1)@Document注解會對實體中的所有屬性建立索引:
- indexName = "customer":表示建立一個名為customer的索引。
- type="customer":表示在索引中建立一個名為customer的類别,而在Elasticsearch 7.x版本中取消了類别的概念。
- shards = 1:表示隻使用一個分片,預設為5。
- replicas = 0:表示副本數量,預設為1,0表示不使用副本。
- refreshInterval = "-1":表示禁止索引重新整理。
(2)@Id作用在成員變量,标記一個字段作為id主鍵。
(3)@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',運作單元測試方法,檢視索引資料是否插入成功,運作結果如下圖所示:
結果表明索引資料儲存成功,并且通過id能查詢到儲存的索引資料資訊,說明在Spring Boot中成功內建Elasticsearch。
最後
以上,介紹了Spring Boot項目中使用Elasticsearch,一步一步地實作搜尋引擎的功能。