一. 选型
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)是最优的选择
二. SpringBoot整合
1. 引入依赖pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xz</groupId>
<artifactId>springboot-elasticsearch</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.11.1</version>
</dependency>
</dependencies>
</project>
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(
"127.0.0.1", 9200, "http"
)));
}
}
3. 测试
测试 搜索address中包含 mill的所有人的年龄分布以及平均年龄
GET address/_search
{
"query": {
"match": {
"address": "Mill"
}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age",
"size": 10
}
},
"ageAvg": {
"avg": {
"field": "age"
}
},
"balanceAvg": {
"avg": {
"field": "balance"
}
}
},
"size": 0
}
测试代码
@SpringBootTest
public class ClientApplicationTest {
@Autowired
private 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);
}
/**
* 搜索address中包含 mill的所有人的年龄分布以及平均年龄
*
* @throws Exception
*/
@Test
void test() throws Exception {
// 创建检索请求
SearchRequest searchRequest = new SearchRequest();
// 指定索引
searchRequest.indices("address");
// 指定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);
// 计算平均年龄
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 aggAge = aggregations.get("aggAge");
for (Terms.Bucket bucket : aggAge.getBuckets()) {
String keyAsString = bucket.getKeyAsString();
System.out.println("年龄: " + keyAsString + " 岁的有 " + bucket.getDocCount() + " 人");
}
Avg balanceAvg1 = aggregations.get("balanceAvg");
System.out.println("平均年龄: " + balanceAvg1.getValue());
}
}