從零搭建Spring Boot腳手架(7):Elasticsearch應該獨立服務
阿新 • • 發佈:2020-09-24
## 1. Spring Data Elasticsearch
**Spring Data Elasticsearch**是**Spring Data**專案的子專案,提供了**Elasticsearch**與**Spring**的整合。實現了**Spring Data Repository**風格的**Elasticsearch**文件互動風格,讓你輕鬆進行**Elasticsearch**客戶端開發。
## 2. 個人的一些看法
應粉絲要求特地將**Elasticsearch**整合到**Spring Boot** 中去。本來打算整合到**kono**腳手架中,但是轉念一想這樣並不是非常合適,一般搜尋建議作為一個獨立的平臺運作,小公司可作為一個獨立的服務,大公司可作為一個搜尋中臺。一般我認為雖然**Elasticsearch**提供了搜尋功能,大部分情況下我們並不像常規的關係型資料庫一樣進行直接寫入,而是通過同步的方式進行同步或者預熱寫入資料。
![資料通過Logstash同步到ES](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fed296bc76be452eaebabd41597a87e7~tplv-k3u1fbpfcp-zoom-1.image)
具體的架構不是本文要講的,在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** :
```xml
```
關於配置有兩種一種面向傳統的**Restful**:
```yaml
spring:
elasticsearch:
rest:
# 逗號分隔的Elasticsearch例項使用的列表
uris: http://localhost:9200
# 連結超時時間
connection-timeout:
# 讀取超時時間
read-timeout:
# ES 使用者名稱
username:
# ES 密碼
password:
```
> 如果你都採用預設的配置,可以什麼都不配置,包括`uris`。
另一種面向反應式:
```yaml
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`:
```json
{
"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**物件為:
```java
/**
* @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詞彙的標題的文件,同時查詢詞彙高亮**
```java
@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);
Se