聚合查询
- 指标聚合:相当于mysql的聚合函数,比如max、min、avg、sum等
- 桶聚合:相当于mysql的group by操作。注意:不要对text类型的数据进行分组,会失败,因为text类型会进行分词,分完词之后就是不同的词条进行存储了,而分组希望的是一个整体和其他的进行比对,所以text类型的不要使用分组,keyword的可以。
1、指标聚合(聚合函数)
# 指标聚合 聚合函数
GET goods/_search
{
"query": {
"match": {
"title": "title1"
}
},
"aggs": {
"max_price": {
"max": {
"field": "price"
}
},
"avg_price":{
"avg": {
"field": "price"
}
},
"sum_price":{
"sum": {
"field": "price"
}
}
}
}
在获取查询结果的同时,多计算一下聚合函数的结果。
2、桶聚合(分组查询)
# 桶聚合 分组
GET goods/_search
{
"query": {
"match": {
"title": "title1"
}
},
"aggs": {
"goods_brands": {
"terms": {
"field": "brandName",
"size": 1
}
}
}
}
/**
* 聚合查询:桶聚合 分组查询
* 1、查询title包含title1的数据
* 2、查询品牌列表
*/
@Test
public void testAggQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 1、查询title包含title1的数据
QueryBuilder queryStringQuery = QueryBuilders.matchQuery("title", "title1");
sourceBuilder.query(queryStringQuery);
// 2、查询品牌列表(第一个参数是自定义的名称,用于获取数据;第二个参数是分组的字段名)
AggregationBuilder agg = AggregationBuilders.terms("goods_brands").field("brandName");
sourceBuilder.aggregation(agg);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits searchHits = searchResponse.getHits();
long value = searchHits.getTotalHits().value;
System.out.println("总记录数:" + value);
SearchHit[] hits = searchHits.getHits();
List<Goods> goodsList = new ArrayList<>();
for (SearchHit hit : hits) {
String sourceAsString = hit.getSourceAsString();
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
goodsList.forEach(c -> System.out.println(JSON.toJSONString(c)));
// 看脚本语句的返回值可以发现:aggregations与hits同级
/**
* "aggregations" : {
* "goods_brands" : {
* "doc_count_error_upper_bound" : 0,
* "sum_other_doc_count" : 0,
* "buckets" : [
* {
* "key" : "brandName1",
* "doc_count" : 1
* }
* ]
* }
* }
*/
Aggregations aggregations = searchResponse.getAggregations();
Map<String, Aggregation> stringAggregationMap = aggregations.asMap();
Terms goodsBrands = (Terms) stringAggregationMap.get("goods_brands");
List<? extends Terms.Bucket> buckets = goodsBrands.getBuckets();
List<Object> brands = new ArrayList<>();
for (Terms.Bucket bucket : buckets) {
Object key = bucket.getKey();
brands.add(key);
}
brands.forEach(System.out::println);
}