有多种操作ElasticSearch的客户端:
- 9300端口+TCP连接 7.X不建议使用,8以后放弃
- 9200端口+HTTP连接 官方推荐Rest-Client,封装了ES操作,API层次分明
配置工作----不使用SpringData的方式
1. 依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.4.2</version>
</dependency>
2. 配置
@Configuration
public class ElasticSearchConfig {
@Bean
public RestHighLevelClient esRestClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder( //如果有多个集群,则可继续配置
new HttpHost("139.224.48.195",9200,"http")
)
);
return client;
}
}
API操作
@SpringBootTest
public class ElasticsearcjApplicationTests {
@Autowired
private RestHighLevelClient client;
//测试新增文档
@Test
public void testAddData() throws IOException {
IndexRequest indexRequest = new IndexRequest("goods"); //参数为index的名称
//indexRequest.id(); //自动生成文档id
indexRequest.id("2"); //手动设置文档id
//设置文档数据
//1. source传入k-v键值对
//indexRequest.source("goodName","铅笔","goodPrice",15,"goodType","学习用品");
//2. source传入对象---最常用
Good good = new Good("橡皮",16,"学习用品");
String s = JSON.toJSONString(good);
indexRequest.source(s, XContentType.JSON);
//保存操作
//1. 同步保存
IndexResponse index = client.index(indexRequest, RequestOptions.DEFAULT);
//2. 异步保存
}
@Data
@AllArgsConstructor
class Good{
private String goodName;
private Integer goodPrice;
private String goodType;
}
//测试查询文档
@Test
public void testSearchData() throws IOException {
//1. 创建检索请求
SearchRequest request = new SearchRequest();
//2. 从哪个索引检索
request.indices("bank");
//3. 指定DSL
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//3.1 构造查询条件
sourceBuilder.query(QueryBuilders.matchQuery("address","mill"));
//3.2 构造聚合条件 AggregationBuilders.terms(聚合名称).field(聚合字段)
TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);//按照年龄聚合
sourceBuilder.aggregation(ageAgg);
AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("balanceAvg").field("balance");
sourceBuilder.aggregation(balanceAvg);
// sourceBuilder.from(5);
// sourceBuilder.size(5);
request.source(sourceBuilder);
System.out.println(sourceBuilder.toString());
//4. 执行检索
SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
System.out.println(searchResponse.toString());
//5. 获取Hit结果
//Map result = JSON.parseObject(searchResponse.toString(), Map.class); //可以转换为map,获取数据
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
// 元数据: searchHit.getIndex(); searchHit.getId(); searchHit.getScore();
// searchHit.getSourceAsMap(); //将数据转换为map
String sourceAsString = searchHit.getSourceAsString();
Account account = JSON.parseObject(sourceAsString, Account.class);
System.out.println("account="+account);
}
//6. 获取聚合结果
Aggregations aggregations = searchResponse.getAggregations();
Terms ageAgg1 = aggregations.get("ageAgg");
for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
String keyAsString = bucket.getKeyAsString();
System.out.println("年龄="+keyAsString+"的人数为:"+bucket.getDocCount());
}
}
}
注:如果只引入elasticsearch-rest-high-level-client,不引入elasticsearch的依赖则会报错:
java.lang.IncompatibleClassChangeError:
Found interface org.elasticsearch.common.bytes.BytesReference, but class