原生es的复杂查询
相关依赖
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.17.6</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.17.6</version>
</dependency>
复杂查询概述
复杂查询本文指通过esClient.search()
方法进行的查询。
查询的代码框架为:
private static void query() throws IOException {
SearchRequest searchRequest = new SearchRequest("要查询的索引名称");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
QueryBuilder queryBuilder = null;
// 对queryBuilder 进行相关赋值
searchSourceBuilder.query(queryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response = esClient.search(searchRequest,RequestOptions.DEFAULT);
}
在上述查询的代码框架中,有一个类SearchSourceBuilder
和一个接口QueryBuilder
需要关注,其二者的关系为searchSourceBuilder.query(queryBuilder)
:QueryBuilder
为SearchSourceBuilder
类的query
方法的入参。
本文概括性的将esClient.search()
分为两大类型的查询操作,分别定义为外层查询,以及内层查询,外层查询相关操作可以通过SearchSourceBuilder
进行实现,内层查询可通过QueryBuilder
进行实现。
通过SearchSourceBuilder
的相关方法,可以实现分页查询
,聚类查询
,对查询结果排序
,过滤查询结果字段
等对查询结果进行操作的功能;通过QueryBuilder
则可实现具体的查询功能,如模糊查询
,组合查询
,条件查询
,全量查询
等具体查询功能,下面分别对这两大类查询做代码举例。
外层查询-SearchSourceBuilder(类)
外层查询概述
外层查询主要是对 SearchSourceBuilder
进行操作,查询的代码框架如下,下文将通过对代码框架中的dealSearchSourceBuilder
方法做修改来实现各种外层查询功能。
private static void query() throws IOException {
SearchRequest searchRequest = new SearchRequest("要查询的索引名称");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 外层操作,对SearchSourceBuilder进行相关操作
dealSearchSourceBuilder(searchSourceBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response = esClient.search(searchRequest,RequestOptions.DEFAULT);
System.err.println(Arrays.toString(response.getHits().getHits()));
}
private static void dealSearchSourceBuilder(SearchSourceBuilder searchSourceBuilder){
}
对查询结果进行分页
分页查询使用SearchSourceBuilder
的from
和size
方法,from
方法入参为索引起始位置(从0开始),size
方法入参为要查询的条数。示例代码如下:
private static void dealSearchSourceBuilder(SearchSourceBuilder searchSourceBuilder){
searchSourceBuilder.from(0).size(1);
}
对查询结果进行排序
private static void dealSearchSourceBuilder(SearchSourceBuilder searchSourceBuilder){
searchSourceBuilder.sort("age", SortOrder.ASC);
}
对查询结果字段进行过滤
private static void dealSearchSourceBuilder(SearchSourceBuilder searchSourceBuilder){
// 查询结果需保留的字段
String[] includesFields = {"a","b"};
// 查询结果不需要的字段
String[] excludesFields = {"c","d"};
searchSourceBuilder.fetchSource(includesFields,excludesFields);
}
对查询结果进行聚合
聚合查询通过 searchSourceBuilder.aggregation
实现,aggregation
方法的入参由AggregationBuilders
进行构建,这里简单的举两个例子。
求年龄的最大值
private static void dealSearchSourceBuilder(SearchSourceBuilder searchSourceBuilder){
MaxAggregationBuilder maxAggregationBuilder =
AggregationBuilders.max("age").field("age");//
searchSourceBuilder.aggregation(maxAggregationBuilder);
}
获取聚合结果
根据年龄进行分组
private static void dealSearchSourceBuilder(SearchSourceBuilder searchSourceBuilder){
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("ageAlias").field("age");
searchSourceBuilder.aggregation(termsAggregationBuilder);
}
获取聚合-分组结果使用
ParsedMax parsedMax = response.getAggregations().get("agaGroup");
SearchResponse response = esClient.search(searchRequest,RequestOptions.DEFAULT);
// 分组结果用 Terms 接收
Terms terms = response.getAggregations().get("agaGroup");
List<? extends Terms.Bucket> buckets = terms.getBuckets();
buckets.forEach(el->{
System.err.println(el.getKey());
System.err.println(el.getDocCount());
});
内层查询-QueryBuilder(接口)
概述
外层查询主要是对 SearchSourceBuilder.query
方法进行操作,query方法的入参通过QueryBuilders
工具类来进行构建.查询的代码框架如下,下文将通过对代码框架中的dealSearchSourceBuilderQuery
方法做修改来实现各种外层查询功能。
private static void query() throws IOException {
SearchRequest searchRequest = new SearchRequest("demo");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 对 searchSourceBuilder.query 传参数进行处理
dealSearchSourceBuilderQuery(searchSourceBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response = esClient.search(searchRequest,RequestOptions.DEFAULT);
System.err.println(Arrays.toString(response.getHits().getHits()));
}
private static void dealSearchSourceBuilderQuery(SearchSourceBuilder searchSourceBuilder){
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
}
全量查询
private static void dealSearchSourceBuilderQuery(SearchSourceBuilder searchSourceBuilder){
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
}
条件查询
private static void dealSearchSourceBuilderQuery(SearchSourceBuilder searchSourceBuilder){
searchSourceBuilder.query(QueryBuilders.termQuery("age",17));
}
多条件查询
private static void dealSearchSourceBuilderQuery(SearchSourceBuilder searchSourceBuilder){
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("age",17));
boolQueryBuilder.should(QueryBuilders.termQuery("name","xiaoming"));
boolQueryBuilder.mustNot(QueryBuilders.termQuery("tel","110"));
searchSourceBuilder.query(boolQueryBuilder);
}