1.ES提供了兩個JAVA REST client 版本
Java Low Level REST Client: 低級別的REST客戶端,通過http與集群交互,用戶需自己編組請求JSON串,及解析響應JSON串。兼容所有ES版本。
Java High Level REST Client: 高級別的REST客戶端,基於低級別的REST客戶端,增加了編組請求JSON串、解析響應JSON串等相關api。使用的版本需要保持和ES服務端的版本一致,否則會有版本問題。
2.創建連接
@Override
public RestHighLevelClient elasticsearchClient() {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(username, password)); //es賬號密碼(默認用戶名為elastic)
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost(esHost, esPort, "http"))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
}));
return client;
}
@Bean
public RestHighLevelClient esRestClient(){
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(username, password)); //es賬號密碼(默認用戶名為elastic)
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost(esHost, esPort, "http"))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
}));
return client;
}
3.執行查詢
SearchRequest 搜索請求對象
SearchSourceBuilder 搜索內容參數設置對象
SearchRequest searchRequest = new SearchRequest(); //首先創建搜索請求對象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//創建搜索內容參數設置對象
searchSourceBuilder.query(boolQueryBuilder);//設置搜索條件
searchRequest.source(searchSourceBuilder);//將SearchSourceBuilder對象添加到搜索請求中
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//開始位置
sourceBuilder.from(from);
//每頁數量
sourceBuilder.size(size);
//排序
sourceBuilder.sort("timeEnd", SortOrder.DESC);
//搜索請求對象
SearchRequest rq = new SearchRequest();
//索引
rq.indices(index);
//各種組合條件
rq.source(sourceBuilder);
//請求
SearchResponse rp = client().search(rq);
4.查詢語句構建
4.1.構建查詢語句
BoolQueryBuilder queryBuilder = boolQuery();
4.2查詢條件組合關系
must: AND
mustNot: NOT
should: OR should: OR
queryBuilder.must(QueryBuilders.termQuery("user", "kimchy"))
.mustNot(QueryBuilders.termQuery("message", "nihao"))
.should(QueryBuilders.termQuery("gender", "male"));
4.3 查詢子條件
matchQuery:會將搜索詞分詞,再與目標查詢字段進行匹配,若分詞中的任意一個詞與目標字段匹配上,則可查詢到。
termQuery:不會對搜索詞進行分詞處理,而是作為一個整體與目標字段進行匹配,若完全匹配,則可查詢到。
4.3.1 matchAllQuery匹配所有
QueryBuilders.matchAllQuery();
4.3.2 termQuery精准匹配
QueryBuilders.termQuery("key", value)//匹配一個
QueryBuilders.termsQuery("key", obj1, obj2..) //匹配多個
4.3.3 matchPhraseQuery對中文精確匹配
QueryBuilders.matchPhraseQuery("key", value)
4.3.4 matchQuery 單個匹配(分詞匹配)
QueryBuilders.matchQuery(key, value)
4.3.5 multiMatchQuery("text", "field1", "field2"..)匹配多個字段, field有通配符就行
QueryBuilders.multiMatchQuery(value, key1, key2, key3);
4.3.6 matchPhrasePrefixQuery 左前綴匹配
QueryBuilders.matchPhrasePrefixQuery(key, value);
4.3.7wildcard query 通配符查詢,支持 * 任意字符串;?任意一個字符
QueryBuilders.wildcardQuery("channelCode","*ctr*")
5.一些查詢例子
/**
* 精確匹配查詢
*/
@GetMapping("/termQuery")
public void termQuery1(){
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("name","新頁工廠測試"));
Iterable<EsStudent> search = esStudentRepository.search(boolQueryBuilder);
}
/**
* 模糊查詢
*/
@GetMapping("/likeQuery")
public void likeQuery(){
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.wildcardQuery("name","*2019*"));
Iterable<EsStudent> search = esStudentRepository.search(boolQueryBuilder);
}
/**
* 空值查詢 null 或者空字符串
*/
@GetMapping("/nullQuery")
public void nullQuery(){
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//構建子查詢
BoolQueryBuilder userUnitBuilder = boolQuery();
//不存在該字段
userUnitBuilder.should(QueryBuilders.boolQuery().mustNot(existsQuery("name")));
//字段為""
userUnitBuilder.should(termQuery("name", ""));
boolQueryBuilder.must(userUnitBuilder);
Iterable<EsStudent> search = esStudentRepository.search(boolQueryBuilder);
}
/**
* 字段不為空查詢
*/
@GetMapping("/notNullQuery")
public void notNullQuery(){
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//構建子查詢
BoolQueryBuilder userUnitBuilder = boolQuery();
//不存在該字段
userUnitBuilder.should(QueryBuilders.boolQuery().mustNot(existsQuery("name")));
//字段為""
userUnitBuilder.should(termQuery("name", ""));
boolQueryBuilder.mustNot(userUnitBuilder);
Iterable<EsStudent> search = esStudentRepository.search(boolQueryBuilder);
}
/**
* 左前綴匹配
*/
@GetMapping("/prefixQuery")
public void prefixQuery1(){
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(prefixQuery("name","新頁"));
Iterable<EsStudent> search = esStudentRepository.search(boolQueryBuilder);
}
/**
* 獲取數據條數
*/
@GetMapping("/countStudent")
public String countStudent() throws IOException {
// 通過CountRequest查詢獲得count
CountRequest countRequest = new CountRequest();
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(prefixQuery("name","新頁"));
sourceBuilder.query(boolQueryBuilder);
// 綁定索引名
countRequest.indices("es_student");
countRequest.source(sourceBuilder);
CountResponse response = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
long count=response.getCount();
return count+"";
}
/**
* 聚合統計
*/
@GetMapping("/aggStudent")
public String aggStudent() throws IOException {
SearchRequest request = new SearchRequest(STUDENT_INDEX);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(prefixQuery("name","新頁"));
sourceBuilder.query(boolQueryBuilder);
ValueCountAggregationBuilder peopleNum = AggregationBuilders.count("peopleNum").field("name");
SumAggregationBuilder totalAge = AggregationBuilders.sum("totalAge").field("age");
request.source(sourceBuilder);
sourceBuilder.size(0);
request.source().aggregation(peopleNum);
request.source().aggregation(totalAge);
SearchResponse search =restHighLevelClient.search(request, RequestOptions.DEFAULT);
//統計處理結果集
Map<String, Aggregation> resultMap = search.getAggregations().asMap();
Aggregation peopleNumAgg = resultMap.get("peopleNum");
Aggregation totalAgeAgg = resultMap.get("totalAge");
double totalAgeD = ((ParsedSum) totalAgeAgg).getValue();
long peopleNumL = ((ParsedValueCount) peopleNumAgg).getValue();
return "總人數:"+peopleNumL+" 總年齡:"+totalAgeD;
}