Elasticsearch 7.x 版本
阿新 • • 發佈:2022-05-17
總結:
- springboot版本選擇的小技巧;
- 在專案的
External Libraries
中搜索elasticsearch
,可以發現elasticsearch-7.6.2.jar
這個依賴,然後開啟其中的MANIFEST.MF
檔案,通過jar包中的X-Compile-Elasticsearch-Version
屬性,我們可以找到相容的Elasticsearch版本號為7.6.2
;
- 在專案的
- ElasticsearchTemplate不建議使用了,改為使用ElasticsearchRestTemplate,ElasticsearchRepository實現複雜查詢的方法也不建議使用了。從此我們簡單的資料操作可以使用ElasticsearchRepository,而複雜的資料操作只能使用ElasticsearchRestTemplate了
- 原來我們用來配置Elasticsearch訪問路徑和叢集名稱的配置已經不建議使用了;取而代之的是直接配置Elasticsearch的rest訪問地址
版本選擇
既然我們要升級到Elasticsearch
7.x
版本,首先要選擇合適的版本。如何選擇合適的版本,這裡有個小技巧分享給大家。
- 首先我們可以在
pom.xml
中修改SpringBoot依賴的版本為2.3.0
;
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
- 然後在專案的
External Libraries
中搜索elasticsearch
,可以發現elasticsearch-7.6.2.jar
這個依賴;
- 然後開啟其中的
MANIFEST.MF
檔案,通過jar包中的X-Compile-Elasticsearch-Version
屬性,我們可以找到相容的Elasticsearch版本號為7.6.2
;
- 之前還有試過兩個版本
6.2.2
版本和7.4.0
版本,發現與SpringBoot 2.3.0 都有相容性問題,所以選擇合適的版本很重要! - 還有一點值得注意的是,如果你使用了中文分詞器(IK Analysis),也要選擇對應的版本
7.6.2
,對於使用Kibana和Logstash也是如此。
遇到的問題
選擇好了合適的Elasticsearch版本後,接下來我們來講講升級版本遇到的問題了!
- 在
application.yml
中,原來我們用來配置Elasticsearch訪問路徑和叢集名稱的配置已經不建議使用了;
- 取而代之的是直接配置Elasticsearch的rest訪問地址;
spring:
elasticsearch:
rest:
uris: http://localhost:9200
- 其實最大的問題還是ElasticsearchTemplate已經過時了,不建議使用了,之前複雜的資料操作用到了它;
- 推薦使用的是ElasticsearchRestTemplate,這大概就是修改
application.yml
中那兩個配置的原因了,修改為使用ElasticsearchRestTemplate後,我們可以發現原來ElasticsearchTemplate的query()
方法已經沒有了;
- 可以使用ElasticsearchRestTemplate的
search()
方法來代替,原來的複雜查詢將有以下改進;
// 使用ElasticsearchTemplate進行復雜查詢
return elasticsearchTemplate.query(searchQuery, response -> {
LOGGER.info("DSL:{}",searchQuery.getQuery().toString());
return convertProductRelatedInfo(response);
});
// 使用ElasticsearchRestTemplate進行復雜查詢
SearchHits<EsProduct> searchHits = elasticsearchRestTemplate.search(searchQuery, EsProduct.class);
return convertProductRelatedInfo(searchHits);
- 我們轉換聚合結果物件的方法
convertProductRelatedInfo
也改進下,只是改變了方法引數型別而已;
//改進前
private EsProductRelatedInfo convertProductRelatedInfo(SearchResponse response) {
//省略方法體程式碼...
}
//改進後
private EsProductRelatedInfo convertProductRelatedInfo(SearchHits<EsProduct> response) {
//省略方法體程式碼...
}
- 如果你覺得這樣就行了,那你呼叫下介面就會發現,報了個型別轉換異常;
2020-07-21 14:40:48.154 ERROR 11616 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed;
nested exception is java.lang.ClassCastException: org.elasticsearch.search.aggregations.bucket.nested.ParsedNested cannot be cast to org.elasticsearch.search.aggregations.bucket.nested.InternalNested] with root cause
java.lang.ClassCastException: org.elasticsearch.search.aggregations.bucket.nested.ParsedNested cannot be cast to org.elasticsearch.search.aggregations.bucket.nested.InternalNested
at com.macro.mall.tiny.service.impl.EsProductServiceImpl.convertProductRelatedInfo(EsProductServiceImpl.java:254) ~[classes/:na]
at com.macro.mall.tiny.service.impl.EsProductServiceImpl.searchRelatedInfo(EsProductServiceImpl.java:229) ~[classes/:na]
at com.macro.mall.tiny.controller.EsProductController.searchRelatedInfo(EsProductController.java:104) ~[classes/:na]
- 我們對該問題進行修復,主要就是原來的
Terms
物件都被改為了ParsedTerms
相關物件,比如說StringTerms被改為了ParsedStringTerms物件,具體對比如下;
- 我們還發現原來使用的ElasticsearchRepository的
search()
方法也過時了,不建議使用了,我們以前用它做了一些複雜查詢;
- 我們可以改用ElasticsearchRestTemplate的
search()
方法來實現,具體實現對比如下;
// ElasticsearchRepository實現複雜搜尋
return productRepository.search(searchQuery)
// ElasticsearchRestTemplate實現複雜搜尋
SearchHits<EsProduct> searchHits = elasticsearchRestTemplate.search(searchQuery, EsProduct.class);
if(searchHits.getTotalHits()<=0){
return new PageImpl<>(null,pageable,0);
}
List<EsProduct> searchProductList = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
return new PageImpl<>(searchProductList,pageable,searchHits.getTotalHits());
Elasticsearch從6.x
升級到7.x
改動還真不是一般的大,ElasticsearchTemplate不建議使用了,改為使用ElasticsearchRestTemplate,ElasticsearchRepository實現複雜查詢的方法也不建議使用了。從此我們簡單的資料操作可以使用ElasticsearchRepository,而複雜的資料操作只能使用ElasticsearchRestTemplate了。