SpringBoot整合ElasticSearch
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());
}