1. Spring Data Elasticsearch
Spring Data Elasticsearch是Spring Data專案的子專案,提供了Elasticsearch與Spring的整合。實現了Spring Data Repository風格的Elasticsearch文件互動風格,讓你輕鬆進行Elasticsearch客戶端開發。
2. 個人的一些看法
應粉絲要求特地將Elasticsearch整合到Spring Boot 中去。本來打算整合到kono腳手架中,但是轉念一想這樣並不是非常合適,一般搜尋建議作為一個獨立的平臺運作,小公司可作為一個獨立的服務,大公司可作為一個搜尋中臺。一般我認為雖然Elasticsearch提供了搜尋功能,大部分情況下我們並不像常規的關係型資料庫一樣進行直接寫入,而是通過同步的方式進行同步或者預熱寫入資料。
具體的架構不是本文要講的,在ES的CSDN官方部落格裡面有比較具體的解決方案。本文是在你已經搭建好Elasticsearch叢集的前提下進行的。
2. 版本對應
相關專案的版本對應關係如下:
Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Boot |
---|---|---|---|
Neumann | 4.0.x | 7.6.2 | 2.3.x |
Moore | 3.2.x | 6.8.6 | 2.2.x |
Lovelace | 3.1.x | 6.2.2 | 2.1.x |
Kay | 3.0.x | 5.5.0 | 2.0.x |
Ingalls | 2.1.x | 2.4.0 | 1.5.x |
根據我平常的做法,我選擇Elasticsearch 7.6.2和Spring Boot 2.3.3作為版本基準進行整合。
3. 依賴引入及配置
只需要引入下面的依賴就可以整合Elasticsearch :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
關於配置有兩種一種面向傳統的Restful:
spring:
elasticsearch:
rest:
# 逗號分隔的Elasticsearch例項使用的列表
uris: http://localhost:9200
# 連結超時時間
connection-timeout:
# 讀取超時時間
read-timeout:
# ES 使用者名稱
username:
# ES 密碼
password:
如果你都採用預設的配置,可以什麼都不配置,包括
uris
。
另一種面向反應式:
spring:
data:
elasticsearch:
client:
# 反應式相關的配置
reactive:
# 端點
endpoints:
connection-timeout:
max-in-memory-size:
socket-timeout:
use-ssl:
username:
password:
這裡配合的是Spring Webflux反應式框架,我個人其實更加傾向於此,但是作為目前的主流還是選擇了第一種。
務必保證
spring.data.elasticsearch.repositories.enabled = true
,否則無法使用Spring Data Repository模式。
4. 操作
這裡演示面向傳統的Restful,一共有兩種風格。假如我們向寫入了Blog
:
{
"blogId": "132435553",
"blogTitle": "腳手架整合elasticsearch",
"author": "felord",
"content": "全稱為Object Storage Service,也叫物件儲存服務,是一種解決和處理離散單元的方法,可提供基於分散式系統之上的物件形式的資料儲存服務,具有可擴充、可管理、低成本等特點,支援中心和邊緣儲存,能夠實現儲存需求的彈性伸縮,主要應用於海量資料管理的各類場景。\n\n這概念真是夠難以理解的。簡單說點我知道的吧,平常我們的檔案地址都是 /User/felord/video/xxx.mp4的目錄樹結構,系統先要找到User,然後一級一級往下找一直到目標為止,這是一種結構化的儲存方式。物件儲存就不一樣了,所有的檔案都放在一個特定的池子裡,只不過檔案的攜帶有它自己的元資訊,通過元資訊去檢索檔案。",
"url": "https://felord.cn/my-spring-boot-day7.html",
"publishedTime": "2020-08-30T22:17:40"
}
對應的POJO物件為:
/**
* @author felord.cn
* @since 2020/8/30 16:10
*/
@Document(indexName = "blogs")
@Data
public class Blog {
@Id
private String blogId;
private String blogTitle;
private String author;
private String content;
private String url;
@Field(type = FieldType.Date,format = DateFormat.date_hour_minute_second)
private LocalDateTime publishedTime;
}
@Document
用來標記文件物件,包含了該文件的一些元資訊,索引副本數,分片數。@Id
文件的識別符號。@Field
文件欄位的一些元資訊配置,型別、名稱、分詞器等等。
主要有以上三種,還有其它的一些註解標記,這裡不再講述。
4.1 ElasticsearchRestTemplate
RedisTemplate
相信你已經不陌生了,同樣的,Spring Data Elasticsearch提供了ElasticsearchRestTemplate
來操作Elasticsearch,增刪改查應有盡有。這裡演示進行復雜的Criteria查詢。
從blogs索引中查詢blogId為132435553而且包含elastic詞彙的標題的文件,同時查詢詞彙高亮
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Test
void testTemplate() {
// 構造條件
Criteria criteria = Criteria.where(new SimpleField("blogId"))
.is("132435553")
.and(new SimpleField("blogTitle"))
.contains("elastic");
CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);
// 高亮
HighlightBuilder blogTitle = SearchSourceBuilder.highlight().field("blogTitle");
HighlightQuery highlightQuery = new HighlightQuery(blogTitle);
criteriaQuery.setHighlightQuery(highlightQuery);
SearchHits<Blog> blogSearchHits = elasticsearchRestTemplate.search(criteriaQuery, Blog.class);
blogSearchHits.getSearchHits().forEach(System.out::println);
}
4.2 Spring Data Repository
Spring Data Repository的核心介面是Repository
。這個介面需要領域類(比如上面的Blog
)跟領域類的ID型別作為引數。這個介面主要是讓你能知道繼承這個類的介面的型別。CrudRepository
提供了對被管理的實體類的一些常用增刪改查方法。那麼針對Elasticsearch提供了各種特色的介面:
Repository模式提供了一種利用方法名稱進行條件構造的查詢方式。
這種方式好處就是語義化,壞處就是方法名稱可能非常的長。對於4.1中的例子我們可以簡化為:
/**
* @author felord.cn
* @since 2020/8/30 21:32
*/
public interface BlogRepository extends ElasticsearchRepository<Blog,String> {
@Highlight(fields = {
@HighlightField(name = "blogTitle")
})
List<SearchHit<Blog>> searchBlogByBlogIdAndBlogTitleContains(String blogId, String titleContains);
}
另一種是採用註解方式,使用@Query
註解,比如我們根據blogId
進行查詢我們可以這麼寫:
@Query("{\"match\": {\"blogId\": \"?0\" }}")
// @Query("{\"match\": {\"blogId\":{\"query\": \"?0\"}}}")
Blog searchById(String blogId);
這個優點就是更加靈活,而且寫法也更加隨意簡單;缺點就是需要熟悉Spring Data Elasticsearch以及Elasticsearch的查詢語法,有一定的學習成本。
總結
以上就是簡單的Spring Data Elasticsearch入門,對於使用Elasticsearch的專案來說,一般都具有了很大的資料量,所以要根據業務的需要進行具體的設計,Spring Data Elasticsearch能讓我們非常方便進行搜尋操作,如果你在使用中遇到什麼問題可以通過公眾號:碼農小胖哥留言進行討論。
關注公眾號:Felordcn 獲取更多資訊