目录
ElactisSearch-Rest-Client
SpringBoot整合ES
ES整合-测试保存
ES整合-测试复杂检索
①通过9300(TCP)访问ES:spring-data-elasticsearch:transport-api.jar
缺点:
1. springboot的版本不同,transport-api.jar不同,不能适配ES的版本
2. 7.x已经不建议使用了,8以后要弃用
②通过9200(HTTP)访问ES
说明:
1. JestClient:非官方,更新慢
2. RestTemplate模拟HTTP请求,ES的很多操作需要自己封装,麻烦
3. HttpClient同上
因此,我们选择ElasticSearch-Rest-Client(elasticsearch-rest-high-level-client),官方的RestClient,封装了ES的操作,API层次分明,上手简单
文档地址:Java High Level REST Client | Java REST Client [7.17] | Elastic
①使用Spring的初始化向导,创建ES服务
说明:为了与之前服务的web版本保持一致,需要将web的版本改为2.3.7
②导入elasticsearch-rest-high-level-client的依赖,将版本改为7.4.2
org.elasticsearch.client
elasticsearch-rest-high-level-client
7.4.2
出现问题:ES的版本并非7.4.2而是7.6.2
问题原因:SpringBoot自己对ES有个版本控制
点进去
再点进去
搜索elasticsearch
解决方案: 将ES的版本改为7.4.2
导入common服务依赖,common中有注册中心和配置中心的依赖
配置注册中心地址以及服务名
添加注解并且排除数据源,因为:common中有数据库连接和mybatis的依赖
参考地址:Initialization | Java REST Client [7.17] | Elastic
@Configuration
public class ElasticSearchConfig {
// @Bean将Bean加入容器,由容器进行管理
@Bean
public RestHighLevelClient ESRestClient(){
RestHighLevelClient client = new RestHighLevelClient (
RestClient.builder ( new HttpHost( "192.168.56.22" , 9200 , "http" )));
return client;
}
}
测试
①设置请求选项
地址:Performing requests | Elasticsearch Java API Client [7.17] | Elastic
private static final RequestOptions COMMON_OPTIONS;
static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
builder.addHeader("Authorization", "Bearer " + TOKEN);
builder.setHttpAsyncResponseConsumerFactory(
new HttpAsyncResponseConsumerFactory
.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
COMMON_OPTIONS = builder.build();
}
我们暂时不需要为请求头设置,因此,先注释掉
地址:Index API | Java REST Client [7.17] | Elastic
最常用的方式:
首先,导入fastjson的依赖
com.alibaba
fastjson
1.2.66
保存或者更新操作
@Test
void indexTest() throws IOException {
// IndexRequest构造器的参数是索引名称
IndexRequest indexRequest=new IndexRequest("users");
// 不设置id的话会默认生成一个id
indexRequest.id("1");
User user=new User();
user.setName("zhangsan");
user.setGender("male");
user.setAge(22);
// toJSONString将对象转化为json格式的String对象
String string = JSON.toJSONString(user);
indexRequest.source(string, XContentType.JSON);
// 保存数据,使用的是index文档中的同步执行
IndexResponse indexResponse =restHighLevelClient.index(indexRequest, ElasticSearchConfig.COMMON_OPTIONS);
// 成功之后的操作
System.out.println(indexResponse);
}
文档参考地址:Search API | Java REST Client [7.17] | Elastic
代码的编写应参考文档
测试用例1:
GET /bank/_search
{
"query": {
"match": {
"address": "mill"
}
}
}
// 1. 创建SearchRequest对象并指定索引
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("bank");
// 2. 创建SearchSourceBuilder对象构造检索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 2.1 使用QueryBuilders工具类构造查询条件
searchSourceBuilder.query(QueryBuilders.matchQuery("address","mill"));
// 打印检索条件
System.out.println(searchSourceBuilder.toString());
// 3. 封装检索条件
searchRequest.source(searchSourceBuilder);
// 4.执行
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
// 5.打印执行结果
System.out.println(searchResponse.toString());
结果:
{"query":{"match":{"address":{"query":"mill","operator":"OR","prefix_length":0,"max_expansions":50,"fuzzy_transpositions":true,"lenient":false,"zero_terms_query":"NONE","auto_generate_synonyms_phrase_query":true,"boost":1.0}}}}
{"took":3,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":4,"relation":"eq"},"max_score":5.4032025,"hits":[{"_index":"bank","_type":"aacount","_id":"970","_score":5.4032025,"_source":{"account_number":970,"balance":19648,"firstname":"Forbes","lastname":"Wallace","age":28,"gender":"M","address":"990 Mill Road","employer":"Pheast","email":"[email protected]","city":"Lopezo","state":"AK"}},{"_index":"bank","_type":"aacount","_id":"136","_score":5.4032025,"_source":{"account_number":136,"balance":45801,"firstname":"Winnie","lastname":"Holland","age":38,"gender":"M","address":"198 Mill Lane","employer":"Neteria","email":"[email protected]","city":"Urie","state":"IL"}},{"_index":"bank","_type":"aacount","_id":"345","_score":5.4032025,"_source":{"account_number":345,"balance":9812,"firstname":"Parker","lastname":"Hines","age":38,"gender":"M","address":"715 Mill Avenue","employer":"Baluba","email":"[email protected]","city":"Blackgum","state":"KY"}},{"_index":"bank","_type":"aacount","_id":"472","_score":5.4032025,"_source":{"account_number":472,"balance":25571,"firstname":"Lee","lastname":"Long","age":32,"gender":"F","address":"288 Mill Street","employer":"Comverges","email":"[email protected]","city":"Movico","state":"MT"}}]}}
使用json在线工具将结果进行一个转化
json在线转换工具地址:在线JSON校验格式化工具(Be JSON)
这一部分是默认的参数
测试用例2:
#搜索address中包含mill的所有人的年龄分布以及平均年龄
GET /bank/_search
{
"query": {
"match": {
"address": "mill"
}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age",
"size": 10
}
},
"avgAgeAgg":{
"avg": {
"field": "age"
}
}
}
}
// 1. 创建SearchRequest对象并指定索引
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("bank");
// 2. 创建SearchSourceBuilder对象构造检索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 2.1 使用QueryBuilders工具类构造查询条件
searchSourceBuilder.query(QueryBuilders.matchQuery("address","mill"));
// 2.2 使用AggregationBuilders工具类构造聚合条件
// 第1个参数为聚合检索的名称,第2个参数为按那个字段分组
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("ageAgg").field("age").size(10);
AvgAggregationBuilder avgAggregationBuilder = AggregationBuilders.avg("avgAgeAgg").field("age");
// 2.3 封装聚合条件
searchSourceBuilder.aggregation(termsAggregationBuilder);
searchSourceBuilder.aggregation(avgAggregationBuilder);
// 打印检索条件
System.out.println(searchSourceBuilder.toString());
// 3. 封装检索条件
searchRequest.source(searchSourceBuilder);
// 4.执行
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
// 5.打印执行结果
System.out.println(searchResponse.toString());
完善代码,将source中数据封装成java中的对象并且拿到聚合的结果
"aggregations": {
"lterms#ageAgg": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [{
"key": 38,
"doc_count": 2
}, {
"key": 28,
"doc_count": 1
}, {
"key": 32,
"doc_count": 1
}]
},
"avg#avgAgeAgg": {
"value": 34.0
}
}
利用json在线工具将source数据转化成java的类
@Test
void testSearch() throws IOException {
// 1. 创建SearchRequest对象并指定索引
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("bank");
// 2. 创建SearchSourceBuilder对象构造检索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 2.1 使用QueryBuilders工具类构造查询条件
searchSourceBuilder.query(QueryBuilders.matchQuery("address","mill"));
// 2.2 使用AggregationBuilders工具类构造聚合条件
// 第1个参数为聚合检索的名称,第2个参数为按那个字段分组
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("ageAgg").field("age").size(10);
AvgAggregationBuilder avgAggregationBuilder = AggregationBuilders.avg("avgAgeAgg").field("age");
// 2.3 封装聚合条件
searchSourceBuilder.aggregation(termsAggregationBuilder);
searchSourceBuilder.aggregation(avgAggregationBuilder);
// 打印检索条件
System.out.println(searchSourceBuilder.toString());
// 3. 封装检索条件
searchRequest.source(searchSourceBuilder);
// 4.执行
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
// 5.将返回结果中source转化成JavaBean
SearchHits searchResponseHits = searchResponse.getHits();
for (SearchHit searchResponseHit : searchResponseHits) {
String source = searchResponseHit.getSourceAsString();
// 使用的fastjson中的parseObject方法将json数据字符串转化成JavaBean
JSONObject account= JSON.parseObject(source);
System.out.println("account"+account);
}
// 6.拿到聚合结果
Aggregations searchResponseAggregations = searchResponse.getAggregations();
Terms ageAgg = searchResponseAggregations.get("ageAgg");
List extends Terms.Bucket> ageAggBuckets = ageAgg.getBuckets();
for (Terms.Bucket ageAggBucket : ageAggBuckets) {
String key = ageAggBucket.getKeyAsString();
long count = ageAggBucket.getDocCount();
System.out.println("key"+"=>"+key+" "+"count"+"=>"+count);
}
Avg avgAgeAgg = searchResponseAggregations.get("avgAgeAgg");
double value = avgAgeAgg.getValue();
System.out.println("value"+"=>"+value);
// 打印执行结果
System.out.println(searchResponse.toString());
}
如何确定get返回的类?
解决方案:
①选中Aggregation
②按CTRL+H
在这里找