主要是通过NativeSearchQueryBuilder 来构建各种查询条件
常用查询
计数
无条件计数(查总量)
ResDomain为ES索引所对应的实体类
NativeSearchQueryBuilder nativeSearchQuery = new NativeSearchQueryBuilder();
elasticsearchTemplate.count(nativeSearchQuery.build(), ResDomain.class)
也可以换种写法,不用实体类进行映射,使用索引名和类型名进行映射
NativeSearchQueryBuilder nativeSearchQuery = new NativeSearchQueryBuilder()
.withIndices(EsConfigConstant.E_RES_DOMAIN_INDEX).withTypes(EsConfigConstant.E_RES_DOMAIN_TYPE);
elasticsearchTemplate.count(nativeSearchQuery.build())
带条件计数(withQuery)
NativeSearchQueryBuilder nativeSearchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.boolQuery().must(QueryBuilders.rangeQuery("createtime").gte(startTime).lte(endTime)))
.withQuery(QueryBuilders.wildcardQuery("license",provinceAbbreviation));
long result = elasticsearchTemplate.count(nativeSearchQuery.build(), ResDomain.class);
注意点
1、QueryBuilders 中包含很多查询条件,基本可以满足所有场景
常用聚合
按单个字段聚合
在某一时间段内,通过icpstatus字段进行聚合,通过聚合value进行降序排序,取前10
//构建查询条件
NativeSearchQueryBuilder searchQuery = new NativeSearchQueryBuilder()
.withIndices(EsConfigConstant.E_RES_DOMAIN_INDEX).withTypes(EsConfigConstant.E_RES_DOMAIN_TYPE)
.withQuery(QueryBuilders.boolQuery().must(QueryBuilders.rangeQuery("createtime").gte(startTime).lte(endTime)))
.addAggregation(AggregationBuilders.terms("icpstatus_agg").field("icpstatus").order(BucketOrder.count(false).size(10));
//获取结果
Aggregations icpstatusAgg = elasticsearchTemplate.query(searchQuery.build(), new ResultsExtractor<Aggregations>() {
@Override
public Aggregations extract(SearchResponse response) {
return response.getAggregations();
}
});
按单个字段多重聚合(先聚合在求和)
在某一时间段内,通过domain字段进行聚合,在通过visitcount进行求和并降序排序取前10
NativeSearchQueryBuilder searchQuery = new NativeSearchQueryBuilder()
.withIndices(EsConfigConstant.E_RES_DOMAIN_INDEX).withTypes(EsConfigConstant.E_RES_DOMAIN_TYPE)
.withQuery(QueryBuilders.rangeQuery("createtime").gte(startTime).lte(endTime))
.addAggregation(AggregationBuilders.terms("domain_agg").field("domain")
.order(BucketOrder.compound(BucketOrder.aggregation("visitcount_agg",false)))
.subAggregation(AggregationBuilders.sum("visitcount_agg").field("visitscount"))
.size(10));
脚本聚合
场景:通过areacode统计地级市数据总量,按聚合结果降序排序
方法:因为areacode具体到区,所以需要取areacode前4位进行聚合,需要通过ES script实现
NativeSearchQueryBuilder searchQuery = new NativeSearchQueryBuilder()
.withIndices(EsConfigConstant.E_RES_DOMAIN_INDEX).withTypes(EsConfigConstant.E_RES_DOMAIN_TYPE)
.withQuery(QueryBuilders.rangeQuery("createtime").gte(startTime).lte(endTime))
.addAggregation(AggregationBuilders.terms("area_agg").script(new Script("def areacode = doc['areacode'].value;return areacode.length()==6?areacode.substring(0,4):areacode"))
.order(BucketOrder.count(false)));
获取聚合结果
NativeSearchQueryBuilder searchQuery = new NativeSearchQueryBuilder()
.withIndices(EsConfigConstant.E_RES_DOMAIN_INDEX).withTypes(EsConfigConstant.E_RES_DOMAIN_TYPE)
.withQuery(QueryBuilders.rangeQuery("createtime").gte(startTime).lte(endTime))
.addAggregation(AggregationBuilders.terms("domain_agg").field("domain")
.order(BucketOrder.compound(BucketOrder.aggregation("visitcount_agg",false)))
.subAggregation(AggregationBuilders.sum("visitcount_agg").field("visitscount"))
.size(10));
聚合结果(返回Terms)
Terms domainTerms = (Terms) domainAgg.asMap().get("domain_agg");
for(Terms.Bucket bucket : domainTerms.getBuckets()){
domainMap.put(bucket.getKey().toString(),bucket.getDocCount());
totalDomain += bucket.getDocCount();
}
求和结果(返回InternalSum)
Terms domainTerms = (Terms) domainAgg.asMap().get("domain_agg");
for(Terms.Bucket bucket : domainTerms.getBuckets()){
InternalSum visitSum = (InternalSum)bucket.getAggregations().asMap().get("visitcount_agg");
result.put(bucket.getKey().toString(),(long)visitSum.getValue());
}