Appearance
聚合查询是es除搜索功能外提供的针对es数据做统计分析的功能。聚合有助于根据搜索查询提供聚合数据。聚合查询是数据库中重要的功能特性,ES作为搜索引擎兼数据库,同样提供了强大的聚合分析能力。它基于查询条件来对数据进行分桶、计算的方法。有点类似于 SQL 中的 group by 再加一些函数方法的操作。
注意:text类型是不支持聚合的。
测试数据
json
# 创建索引 index 和映射 mapping
PUT /fruit
{
"mappings": {
"properties": {
"title":{
"type": "keyword"
},
"price":{
"type":"double"
},
"description":{
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
# 放入测试数据
PUT /fruit/_bulk
{"index":{}}
{"title" : "面包","price" : 19.9,"description" : "小面包非常好吃"}
{"index":{}}
{"title" : "旺仔牛奶","price" : 29.9,"description" : "非常好喝"}
{"index":{}}
{"title" : "日本豆","price" : 19.9,"description" : "日本豆非常好吃"}
{"index":{}}
{"title" : "小馒头","price" : 19.9,"description" : "小馒头非常好吃"}
{"index":{}}
{"title" : "大辣片","price" : 39.9,"description" : "大辣片非常好吃"}
{"index":{}}
{"title" : "透心凉","price" : 9.9,"description" : "透心凉非常好喝"}
{"index":{}}
{"title" : "小浣熊","price" : 19.9,"description" : "童年的味道"}
{"index":{}}
{"title" : "海苔","price" : 19.9,"description" : "海的味道"}
使用
根据某个字段分组
http
GET /fruit/_search
{
"query": {
"term": {
"description": {
"value": "好吃"
}
}
},
"aggs": {
"price_group": {
"terms": {
"field": "price"
}
}
}
}
求最大值
http
GET /fruit/_search
{
"aggs": {
"price_max": {
"max": {
"field": "price"
}
}
}
}
求最小值
http
GET /fruit/_search
{
"aggs": {
"price_min": {
"min": {
"field": "price"
}
}
}
}
求平均值
http
GET /fruit/_search
{
"aggs": {
"price_agv": {
"avg": {
"field": "price"
}
}
}
}
求和
http
GET /fruit/_search
{
"aggs": {
"price_sum": {
"sum": {
"field": "price"
}
}
}
}
整合应用
java
@Test
public void testAggsPrice() throws IOException {
SearchRequest searchRequest = new SearchRequest("fruit");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.aggregation(AggregationBuilders.terms("group_price").field("price"));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = searchResponse.getAggregations();
ParsedDoubleTerms terms = aggregations.get("group_price");
List<? extends Terms.Bucket> buckets = terms.getBuckets();
for (Terms.Bucket bucket : buckets) {
System.out.println(bucket.getKey() + ", "+ bucket.getDocCount());
}
}
java
// 求不同名称的数量
@Test
public void testAggsTitle() throws IOException {
SearchRequest searchRequest = new SearchRequest("fruit");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.aggregation(AggregationBuilders.terms("group_title").field("title"));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = searchResponse.getAggregations();
ParsedStringTerms terms = aggregations.get("group_title");
List<? extends Terms.Bucket> buckets = terms.getBuckets();
for (Terms.Bucket bucket : buckets) {
System.out.println(bucket.getKey() + ", "+ bucket.getDocCount());
}
}
java
// 求和
@Test
public void testAggsSum() throws IOException {
SearchRequest searchRequest = new SearchRequest("fruit");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.aggregation(AggregationBuilders.sum("sum_price").field("price"));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
ParsedSum parsedSum = searchResponse.getAggregations().get("sum_price");
System.out.println(parsedSum.getValue());
}