SpringBoot整合ElasticSearch
1、選型
Java操作ElasticSearch有兩種方式,一個是通過ES的9300端口使用TCP的方式操作,另一種是通過ES的9200端口使用HTTP的方式
1)9300 TCP
spring-data-elasticsearch:transport-api.jar
-
springboot 版本不同, transport-api.jar 不同,不能適配 es 版本
-
7.x 已經不建議使用,8 以后就要廢棄
2)9200 HTTP
-
JestClient:非官方,更新慢
-
RestTemplate:模擬發 HTTP 請求,ES 很多操作需要自己封裝,麻煩
-
HttpClient:同上
-
Elasticsearch-Rest-Client:官方 RestClient,封裝了 ES 操作,API 層次分明,上手簡單
綜上所述,選擇Elasticsearch-Rest-Client(elasticsearch-rest-high-level-client)是最優的選擇,下面記錄如何整合
Elasticsearch-Rest-Client 官方文檔
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html
2、SpringBoot整合
1)引入依賴
<properties>
<java.version>1.8</java.version>
//注意es版本
<elasticsearch.version>7.4.2</elasticsearch.version>
</properties>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.2</version>
</dependency>
2)編寫配置類
@Configuration
public class ElasticSearchConfig {
public static final RequestOptions COMMON_OPTIONS;
static {
// RequestOptions類保存了請求的部分,這些部分應該在同一個應用程序中的許多請求之間共享。
// 創建一個singqleton實例,並在所有請求之間共享它。可以設置請求頭之類的一些配置
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// builder.addHeader("Authorization", "Bearer " + TOKEN);
// builder.setHttpAsyncResponseConsumerFactory(
// new HttpAsyncResponseConsumerFactory
// .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 *1024));
COMMON_OPTIONS = builder.build();
}
//創建ES實例
@Bean
public RestHighLevelClient restHighLevelClient(){
return new RestHighLevelClient(RestClient.builder(new HttpHost(
"192.168.XX.XXX",9200,"http"
)));
}
}
RequestOptions更多配置參考
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-low-usage-requests.html#java-rest-low-usage-request-options
//創建ES實例參考
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-low-usage-initialization.html
3)測試檢索
① 測試保存
@SpringBootTest
class SearchApplicationTests {
@Autowired
RestHighLevelClient restHighLevelClient;
@Test
void contextLoads() throws IOException {
//測試保存
IndexRequest request = new IndexRequest("posts");
request.id("1");
String jsonString = "{" +
"\"user\":\"kimchy\"," +
"\"postDate\":\"2013-01-30\"," +
"\"message\":\"trying out Elasticsearch\"" +
"}";
request.source(jsonString, XContentType.JSON);
IndexResponse index=
restHighLevelClient.index(request,ElasticSearchConfig.COMMON_OPTIONS);
System.out.println("index-------------:"+ index);
}
}
② 測試復雜檢索
測試在Elastic進階檢索中使用kibana寫的案例
參考ElasticSearchAPI
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-search.html
#搜索address中包含 mill的所有人的年齡分布以及平均年齡
@Test
void test() throws IOException {
//搜索address中包含 mill的所有人的年齡分布以及平均年齡
// 創建檢索請求
SearchRequest searchRequest = new SearchRequest();
// 指定索引
searchRequest.indices("bank");
// 指定 DSL 檢索條件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 構建檢索條件 address 包含 mill
searchSourceBuilder.query(QueryBuilders.matchQuery("address","mill"));
// 按照年齡值分布進行聚合
TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
searchSourceBuilder.aggregation(ageAgg);
// 1.3 計算平均薪資
AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("balanceAvg").field("balance");
searchSourceBuilder.aggregation(balanceAvg);
System.out.println("檢索條件:"+searchSourceBuilder.toString());
searchRequest.source(searchSourceBuilder);
//執行檢索
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
//獲取查詢到的記錄
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
//獲取檢索的分析信息
Aggregations aggregations = searchResponse.getAggregations();
// for (Aggregation aggregation : aggregations.asList()) {
// System.out.println("當前聚合名:" + aggregation.getName());
// }
Terms ageAgg1 = aggregations.get("ageAgg");
for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
String keyAsString = bucket.getKeyAsString();
System.out.println("年齡:" + keyAsString + " 歲的有 " + bucket.getDocCount() + " 人");
}
Avg balanceAvg1 = aggregations.get("balanceAvg");
System.out.println("平均薪資: " + balanceAvg1.getValue());
}