1. 程式人生 > 其它 >Elasticsearch 7.x 版本

Elasticsearch 7.x 版本

總結:

  1. springboot版本選擇的小技巧;
    • 在專案的External Libraries中搜索elasticsearch,可以發現elasticsearch-7.6.2.jar這個依賴,然後開啟其中的MANIFEST.MF檔案,通過jar包中的X-Compile-Elasticsearch-Version屬性,我們可以找到相容的Elasticsearch版本號為7.6.2
  2. ElasticsearchTemplate不建議使用了,改為使用ElasticsearchRestTemplate,ElasticsearchRepository實現複雜查詢的方法也不建議使用了。從此我們簡單的資料操作可以使用ElasticsearchRepository,而複雜的資料操作只能使用ElasticsearchRestTemplate了
  3. 原來我們用來配置Elasticsearch訪問路徑和叢集名稱的配置已經不建議使用了;取而代之的是直接配置Elasticsearch的rest訪問地址

版本選擇

既然我們要升級到Elasticsearch7.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了。