ElasticSearch7.6x聚合从入门到放弃:使用java聚合的十五个案例

官方文档介绍:https://www.elastic.co/guide/cn/elasticsearch/guide/current/aggs-high-level.html

可以结合官方文档和这篇文章去学习。相关代码可在资源界面获取。

聚合是桶和指标组成的

当聚合开始执行时,每个文档里面的值通过计算来决定符合哪个桶,如果匹配,文档将会被放入对应的桶中

满足特定条件的文档 相当于sql的group by。

多个嵌套级的aggregation,类似于sql多字段分组(group by field1,field2)

指标

对桶内的文档进行统计计算 相当于count(),sum(),max()等统计方法

POST /cars/transactions/_bulk
{ "index": {}}
{ "price" : 10000, "color" : "red", "make" : "honda", "sold" : "2014-10-28" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 30000, "color" : "green", "make" : "ford", "sold" : "2014-05-18" }
{ "index": {}}
{ "price" : 15000, "color" : "blue", "make" : "toyota", "sold" : "2014-07-02" }
{ "index": {}}
{ "price" : 12000, "color" : "green", "make" : "toyota", "sold" : "2014-08-19" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 80000, "color" : "red", "make" : "bmw", "sold" : "2014-01-01" }
{ "index": {}}
{ "price" : 25000, "color" : "blue", "make" : "ford", "sold" : "2014-02-12" }

聚合可以和搜索请求同时进行,默认情况下,聚合与查询是对同一范围进行操作的,也就是说,聚合是基于我们查询的文档集合进行计算的

全文查询和聚合

例一:不同颜色的车分别有多少辆

popular_colors为桶的名称

terms为桶的类型

GET /cars/transactions/_search
{
    "size" : 0,
    "aggs" : { 
        "popular_colors" : { 
            "terms" : { 
              "field" : "color.keyword"
            }
        }
    }
}
 //聚合   不同颜色的车分别有多少辆
    @Test
    public void aagsTest() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest();

        //构建查询创建者
        SearchSourceBuilder ssb = new SearchSourceBuilder();
        //添加聚合条件
        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.
                terms("popular_colors").//设置一个桶的名字  取结果的时候需要用到
                field("color.keyword"); // 聚合的字段    color类型为text 取类型为keyword的子字段color.keyword
        ssb.aggregation(aggregationBuilder);
        request.indices("cars");
        request.source(ssb);

        //执行查询返回查询响应结果
        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //取结果   
        Terms aggs = search.getAggregations().get("popular_colors");
        
        for (Terms.Bucket bucket : aggs.getBuckets()) {
            System.out.println(bucket.getKeyAsString()+"  "+bucket.getDocCount());   
        }
    }

注意:ES在聚合时的字段类型不能为text,但是一般text字段有一个类型为keyword的子字段keyword,keyword类型可以排序和聚合,可以是用字段.子字段,如上面的例子。

类型keyword与text的区别: keyword只能精确查询,不能被分词查询,能聚合、排序。 text类型能模糊查询,能分词查询,不能聚合、排序。

例二:各种颜色车辆平均价格以及代码

get /cars/transactions/_search
{
  "aggs":{
    "popular_colors" :{
      "terms":{
        "field": "color.keyword"
      },
      "aggs":{
        "avg_price":{
          "avg":{
            "field":"price"
          }
        }
      }
    }
  }
}
 // 取各种颜色车的平均价格
    @Test
    public void aggTest2() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");

        //构建查询创建者
        SearchSourceBuilder ssb = new SearchSourceBuilder();
        //添加聚合条件
        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("colors").field("color.keyword").
                subAggregation(AggregationBuilders.avg("avgPrice").field("price"));
        
        ssb.aggregation(aggregationBuilder);
        request.source(ssb);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        
        //取结果
        Terms terms = search.getAggregations().get("colors");
        //取颜色的聚合结果
        for (Terms.Bucket bucket : terms.getBuckets()) {
            Avg avgPrice = bucket.getAggregations().get("avgPrice");
            //取嵌套在第一层结果中的平均价格
            System.out.println(bucket.getKeyAsString() +"    "+ avgPrice.getValue());
            
        }
    }

例三:每个颜色的汽车制造商的分布

GET /cars/transactions/_search
{
   "size" : 0,
   "aggs": {
      "colors": {
         "terms": {
            "field": "color"
         },
         "aggs": {
            "avg_price": { 
               "avg": {
                  "field": "price"
               }
            },
            "make": { 
                "terms": {
                    "field": "make" 
                }
            }
         }
      }
   }
}
//取每种颜色桶的平均价格和颜色桶中不同的制造商
    @Test
    public void aggTest3() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");
        
        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();

        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("colors").field("color.keyword").
                subAggregation(AggregationBuilders.avg("avgPrice").field("price")).
                subAggregation(AggregationBuilders.terms("whereMake").field("make.keyword"));
        
        ssb.aggregation(aggregationBuilder);
        request.source(ssb);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        Terms colorTerm = search.getAggregations().get("colors");
        for (Terms.Bucket bucket : colorTerm.getBuckets()) {
            Avg avgPrice = bucket.getAggregations().get("avgPrice");
            Terms makes = bucket.getAggregations().get("whereMake");
            for (Terms.Bucket makesBucket : makes.getBuckets()) {
                System.out.println(bucket.getKeyAsString()+"   "+avgPrice.getValue()+"   "+makesBucket.getKeyAsString()+"   "+makesBucket.getDocCount());
            }
        }
    }

例四:不同颜色同中为每个汽车生成商计算最低和最高的价格

GET /cars/transactions/_search
{
   "size" : 0,
   "aggs": {
      "colors": {
         "terms": {
            "field": "color"
         },
         "aggs": {
            "avg_price": { "avg": { "field": "price" }
            },
            "make" : {
                "terms" : {
                    "field" : "make"
                },
                "aggs" : { 
                    "min_price" : { "min": { "field": "price"} }, 
                    "max_price" : { "max": { "field": "price"} } 
                }
            }
         }
      }
   }
}
//每种颜色桶的平均价格和 桶中不同的制造商 和  颜色桶中不同厂商的最高价格和最低价格
    @Test
    public void aggsTest() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");

        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();

        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("colors").field("color.keyword").
                subAggregation(AggregationBuilders.avg("avgPrice").field("price")).
                subAggregation(AggregationBuilders.terms("whereMake").field("make.keyword").
                        subAggregation(AggregationBuilders.min("minPrice").field("price")).   //minPrice桶和maxPrice桶是嵌套在whereMake桶中的
                        subAggregation(AggregationBuilders.max("maxPrice").field("price")));


        ssb.aggregation(aggregationBuilder);
        request.source(ssb);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        //获得颜色桶
        Terms colorsTerm = search.getAggregations().get("colors");
        //遍历颜色桶
        for (Terms.Bucket bucket : colorsTerm.getBuckets()) {
            Avg avgPrice = bucket.getAggregations().get("avgPrice");
            //获取颜色桶中的whereMake桶
            Terms makes = bucket.getAggregations().get("whereMake");
            for (Terms.Bucket makesBucket : makes.getBuckets()) {
                Min minPirce = makesBucket.getAggregations().get("minPrice");
                Max maxPrice = makesBucket.getAggregations().get("maxPrice");
                System.out.println(bucket.getKeyAsString()+"   "+avgPrice.getValue()+"   "+makesBucket.getKeyAsString()+
                        "   "+makesBucket.getDocCount()+"   maxPrice:"+maxPrice.getValue()+"   minPrice:"+minPirce.getValue());
            }
        }

    }

例五:每个月销售的车辆数

GET /cars/transactions/_search
{
   "size" : 0,
   "aggs": {
      "sales": {
         "date_histogram": {
            "field": "sold",
            "interval": "month",
            "format": "yyyy-MM-dd",
            "min_doc_count" : 0, 
            "extended_bounds" : { 
                "min" : "2014-01-01",
                "max" : "2014-12-31"
            }
         }
      }
   }
}
//2014年1-12月每个月销售的车辆数
    @Test
    public void aggsTest5() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");

        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();

        //设置时间区间
        ExtendedBounds extendedBounds = new ExtendedBounds("2014-01-01", "2014-12-31");

        DateHistogramAggregationBuilder aggregationBuilder = AggregationBuilders.dateHistogram("sales").field("sold").
                calendarInterval(DateHistogramInterval.MONTH).    //DateHistogramInterval.MONTH参数  设置时间间隔要求为每个月
                format("yyyy-MM-dd").extendedBounds(extendedBounds);    //时间格式转要求
        
        ssb.aggregation(aggregationBuilder);
        request.source(ssb);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        ParsedDateHistogram date = search.getAggregations().get("sales");

        for (Histogram.Bucket bucket : date.getBuckets()) {
            System.out.println(bucket.getKeyAsString()+"   "+bucket.getDocCount());
        }
    }

例六:按季度、每个汽车品牌计算销售总额,同时展示每部车的价格和每个季度的销售数量

GET /cars/transactions/_search
{
   "size" : 0,
   "aggs": {
      "sales": {
         "date_histogram": {
            "field": "sold",
            "interval": "quarter", 
            "format": "yyyy-MM-dd",
            "min_doc_count" : 0,
            "extended_bounds" : {
                "min" : "2014-01-01",
                "max" : "2014-12-31"
            }
         },
         "aggs": {
            "per_make_sum": {
               "terms": {
                  "field": "make"
               },
               "aggs": {
                  "sum_price": {
                     "sum": { "field": "price" } 
                  }
               }
            },
            "total_sum": {
               "sum": { "field": "price" } 
            }
         }
      }
   }
}

在这里插入图片描述

//同时按季度、每个汽车品牌计算销售总额,同时展示每部车的价格和每个季度的销售数量
    @Test
    public void aggsTest6() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");

        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();

        //设置时间区间
        ExtendedBounds extendedBounds = new ExtendedBounds("2014-01-01", "2014-12-31");

        DateHistogramAggregationBuilder aggregationBuilder = AggregationBuilders.dateHistogram("sales").field("sold").
                calendarInterval(DateHistogramInterval.QUARTER).    //DateHistogramInterval.MONTH参数  设置时间间隔要求为每个月
                format("yyyy-MM-dd").         //时间格式转要求
                extendedBounds(extendedBounds).    // 以上为根据季度聚合的桶
                subAggregation(AggregationBuilders.sum("totalPrice").field("price")).    // 根据季度统计总销售额 被包含在季度桶中
                subAggregation(AggregationBuilders.terms("makeSale").field("make.keyword").  // 根据季度桶  再次聚合 每个季度中厂商的桶
                        subAggregation(AggregationBuilders.terms("price").field("price")));    // 根据每季度厂商的桶 聚合 每部车的价格桶
        
        ssb.aggregation(aggregationBuilder);
        request.source(ssb);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        
        ParsedDateHistogram sales = search.getAggregations().get("sales");  //获取按季度统计的桶
        for (Histogram.Bucket bucket : sales.getBuckets()) {    //解析季度统计桶
            Terms makeSale = bucket.getAggregations().get("makeSale");   //解析季度统计桶中聚合的各厂商桶
            Sum totalPrice = bucket.getAggregations().get("totalPrice"); //解析按照季度统计的总销售额
            for (Terms.Bucket totalPriceBucket : makeSale.getBuckets()) {
                Terms price = totalPriceBucket.getAggregations().get("price");   //解析季度统计桶中聚合的各厂商桶中聚合的每部车的价格桶
                for (Terms.Bucket priceBucket : price.getBuckets()) {
                    System.out.println(bucket.getKeyAsString()+"     总价格:"+totalPrice.getValue()+
                            "    厂商:"+totalPriceBucket.getKeyAsString()+"  "+priceBucket.getDocCount()+
                            "   价格:"+priceBucket.getKeyAsString());
                }
            }
        }
    }

在这里插入图片描述

范围限定的聚合

例七:福特已售车有多少种颜色

与例一不同的是 需在福特车品牌范围内获取不同颜色车的个数

GET /cars/transactions/_search
{
    "query" : {
        "match" : {
            "make" : "ford"
        }
    },
    "aggs" : {
        "colors" : {
            "terms" : {
              "field" : "color"
            }
        }
    }
}
 @Test
    public void aagsTest() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest();

        //构建查询创建者
        SearchSourceBuilder ssb = new SearchSourceBuilder();
        //添加聚合条件
        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.
                terms("popular_colors").//设置一个桶的名字  取结果的时候需要用到
                field("color.keyword"); // 聚合的字段    color类型为text 取类型为keyword的子字段color.keyword
        
        ssb.aggregation(aggregationBuilder);
        //封装查询条件范围
        ssb.query(QueryBuilders.matchQuery("make","ford"));
        request.indices("cars");
        request.source(ssb);

        //执行查询返回查询响应结果
        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //取结果   
        Terms aggs = search.getAggregations().get("popular_colors");
        
        for (Terms.Bucket bucket : aggs.getBuckets()) {
            System.out.println(bucket.getKeyAsString()+"  "+bucket.getDocCount());   
        }
    }

例八 全局桶的使用: 福特汽车与所有汽车平均售价的比较

全局桶包含所有的文档,它无视查询的范围。

GET /cars/transactions/_search
{
   "size" : 0,
   "query" : {
       "match" : {
           "make" : "ford"
       }
   },
   "aggs" : {
       "single_avg_price": {
           "avg" : { "field" : "price" } 
       },
       "all": {
           "global" : {}, 
           "aggs" : {
               "avg_price": {
                   "avg" : { "field" : "price" } 
               }
           }
       }
   }
}
// 全局桶的使用: 福特汽车与所有汽车平均售价的比较 
    @Test
    public void aggTest7() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");

        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();

        AvgAggregationBuilder avgAggregationBuilder = AggregationBuilders.avg("avgPrice").field("price");
        GlobalAggregationBuilder globalAggregationBuilder = new GlobalAggregationBuilder("all").
                subAggregation(AggregationBuilders.avg("allAVGPrice").field("price"));


        ssb.aggregation(avgAggregationBuilder);
        ssb.aggregation(globalAggregationBuilder);
        ssb.query(QueryBuilders.matchQuery("make","ford"));
        
        request.source(ssb);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        Avg avgPrice = search.getAggregations().get("avgPrice");

        //获取全局聚合桶
        Global allPrice = search.getAggregations().get("all");
        //根据全局聚合桶获取平均价格桶
        Avg allAVGPrice = allPrice.getAggregations().get("allAVGPrice");
        

        System.out.println("福特车平均价:"+avgPrice.getValue()+
                "     所有汽车平均价:"+allAVGPrice.getValue());
    }

例九:1000美元以上所有车的平均价格

使用filter过滤器会忽略评分,并提升查询效率

在这里插入图片描述

 //1000美元 以上的车的  平均价格
    @Test
    public void aggTest8() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");

        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();

        AvgAggregationBuilder avgPriceBuilder = AggregationBuilders.avg("avgPrice").field("price");

        ssb.aggregation(avgPriceBuilder);
        
        ssb.query(QueryBuilders.constantScoreQuery(
                QueryBuilders.rangeQuery("price").gte(10000f)
        ));
        request.source(ssb);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        Avg avgPrice = search.getAggregations().get("avgPrice");
        System.out.println(avgPrice.getValue());

    }

例十 过滤桶:对结果进行过滤

14年11月份的平均销售额

GET /cars/transactions/_search
{
   "query":{
      "match": {
         "make": "honda"
      }
   },
   "aggs":{
      "recent_sales": {
         "filter": { 
            "range": {
               "sold": {
                  "from": "2014-11-01",
                  "to": "2014-11-30"
               }
            }
         },
         "aggs": {
            "average_price":{
               "avg": {
                  "field": "price" 
               }
            }
         }
      }
   }
}

结果可以看到他是将所有的honda品牌的结果查询出来 ,只是对聚合结果进行过滤

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 0.9444616,
    "hits" : [
      {
        "_index" : "cars",
        "_type" : "transactions",
        "_id" : "_4QSSHgBiVHg5JEIPFIi",
        "_score" : 0.9444616,
        "_source" : {
          "price" : 10000,
          "color" : "red",
          "make" : "honda",
          "sold" : "2014-10-28"
        }
      },
      {
        "_index" : "cars",
        "_type" : "transactions",
        "_id" : "AIQSSHgBiVHg5JEIPFMj",
        "_score" : 0.9444616,
        "_source" : {
          "price" : 20000,
          "color" : "red",
          "make" : "honda",
          "sold" : "2014-11-05"
        }
      },
      {
        "_index" : "cars",
        "_type" : "transactions",
        "_id" : "BIQSSHgBiVHg5JEIPFMj",
        "_score" : 0.9444616,
        "_source" : {
          "price" : 20000,
          "color" : "red",
          "make" : "honda",
          "sold" : "2014-11-05"
        }
      }
    ]
  },
  "aggregations" : {
    "recent_sales" : {
      "doc_count" : 2,
      "average_price" : {
        "value" : 20000.0
      }
    }
  }
}
//   过滤桶:对聚合结果进行过滤    14年11月份的平均销售额
    @Test
    public void aggTest9() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");

        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();

        FilterAggregationBuilder filterAggregationBuilder = AggregationBuilders.filter("lastMonthSales", 
                QueryBuilders.rangeQuery("sold").from("2014-11-01").to("2014-12-01")).
                subAggregation(AggregationBuilders.avg("lastMonthAvgPrice").field("price"));

        ssb.aggregation(filterAggregationBuilder);
        ssb.query(QueryBuilders.matchQuery("make","honda"));
        request.source(ssb);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        Filter filter = search.getAggregations().get("lastMonthSales");
        Avg avg = filter.getAggregations().get("lastMonthAvgPrice");

        System.out.println(avg.getValue());
    }

例十一 后过滤器:只过滤搜索结果,不过滤聚合结果 post_filter

https://www.elastic.co/guide/cn/elasticsearch/guide/current/_post_filter.html

查询福特品牌中不同的颜色以及车辆数,查询结果中只显示绿色福特,但聚合结果全部显示

与过滤桶的效果相反

在这里插入图片描述

//后过滤器:只过滤搜索结果,不过滤聚合结果  post_filter 
//查询福特品牌中不同的颜色以及车辆数,查询结果中只显示绿色福特,但聚合结果全部显示
    @Test
    public void aggsTest10() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");
        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();
        //聚合
        TermsAggregationBuilder allColors = AggregationBuilders.terms("all_colors").field("color.keyword");
        //查询
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("make", "ford");
        //封装条件
        ssb.aggregation(allColors);
        ssb.query(matchQueryBuilder);
        ssb.postFilter(QueryBuilders.termQuery("color","green"));
        
        request.source(ssb);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        Terms colorsTerms = search.getAggregations().get("all_colors");
        for (Terms.Bucket bucket : colorsTerms.getBuckets()) {
            System.out.println(bucket.getKeyAsString()+"   车辆数"+bucket.getDocCount());
        }
    }

使用条件: 当需要对搜索结果和聚合结果做不同的过滤时,你才应该使用 post_filter

post_filter 的特性是在查询 之后 执行,任何过滤对性能带来的好处(比如缓存)都会完全失去。

  • filter 过滤中的 non-scoring 查询,同时影响搜索结果和聚合结果。
  • filter 桶影响聚合。
  • post_filter 只影响搜索结果。

多桶排序

例十二:颜色桶按个数升序排序

GET /cars/transactions/_search
{
    "size" : 0,
    "aggs" : {
        "colors" : {
            "terms" : {
              "field" : "color",
              "order": {
                "_count" : "asc" 
              }
            }
        }
    }
}

关键字_count是按照doc_count值排序的。

order参数可以设置一以下内容:

_count 按文档个数排序。对terms、histogram、date_histogram有效。

_term 按词项的字符串的字母顺序排序,只在terms内使用。

key 按每个桶的键值数值排序(理论上与 _term类似),只在histogram和date_histogram 内使用。

 //颜色桶按个数升序排序
    @Test
    public void aggTest11() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");
        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();

        TermsAggregationBuilder colors = AggregationBuilders.terms("colors").field("color.keyword").order(BucketOrder.count(true));
        
        ssb.aggregation(colors);
        request.source(ssb);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        Terms colorsTerms = search.getAggregations().get("colors");
        for (Terms.Bucket bucket : colorsTerms.getBuckets()) {
            System.out.println(bucket.getKeyAsString()+"    "+bucket.getDocCount());
        }
    }

例十三:颜色桶获取每个桶的平均价并按照平均价排序

GET /cars/transactions/_search
{
    "size" : 0,
    "aggs" : {
        "colors" : {
            "terms" : {
              "field" : "color",
              "order": {
                "avg_price" : "asc" 
              }
            },
            "aggs": {
                "avg_price": {
                    "avg": {"field": "price"} 
                }
            }
        }
    }
}
//颜色桶获取每个桶的平均价并按照平均价排序
    @Test
    public void aggTest12() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");
        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();

        TermsAggregationBuilder colors = 
                AggregationBuilders.terms("colors").field("color.keyword").order(BucketOrder.aggregation("avgPrice",true)).  //order参数中设置平均价桶的名字即可
                subAggregation(AggregationBuilders.avg("avgPrice").field("price"));
        
        ssb.aggregation(colors);
        request.source(ssb);
        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        Terms terms = search.getAggregations().get("colors");
        for (Terms.Bucket bucket : terms.getBuckets()) {
            Avg avgPrice = bucket.getAggregations().get("avgPrice");
            System.out.println(bucket.getKeyAsString()+"    "+bucket.getDocCount()+"     均价"+avgPrice.getValue());
        }
    }

例十四: extended_stats 度量

extended_stats参数中有许多值 如sum、avg、min、max等等,如果需要用来排序可以直接使用 . 的方式设置

GET /cars/transactions/_search
{
    "size" : 0,
    "aggs" : {
        "colors" : {
            "terms" : {
              "field" : "color",
              "order": {
                "stats.variance" : "asc" 
              }
            },
            "aggs": {
                "stats": {
                    "extended_stats": {"field": "price"}
                }
            }
        }
    }
}

部分结果

在这里插入图片描述

//extended_stats 度量 
    @Test
    public void aggTest13() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");
        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();

        TermsAggregationBuilder colors =
                AggregationBuilders.terms("colors").field("color.keyword").order(BucketOrder.aggregation("stats.variance",false)).
                        subAggregation(AggregationBuilders.extendedStats("stats").field("price"));

        ssb.aggregation(colors);
        request.source(ssb);
        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        Terms terms = search.getAggregations().get("colors");
        for (Terms.Bucket bucket : terms.getBuckets()) {
            ExtendedStats stats = bucket.getAggregations().get("stats");
            System.out.println(bucket.getKeyAsString()+"    "+bucket.getDocCount()+" "+stats.getVarianceAsString());  //由于extendedStats有很多值,这里只列出排序的那个值
        }
    }

统计去重后的数量: cardinality

例十五:统计共有多少种颜色

GET /cars/transactions/_search
{
    "size" : 0,
    "aggs" : {
        "distinct_colors" : {
            "cardinality" : {
              "field" : "color"
            }
        }
    }
}
//统计几种颜色的车辆
    @Test
    public void aggTest14() throws IOException {
        //创建查询请求
        SearchRequest request = new SearchRequest("cars");
        //构建查询建造者
        SearchSourceBuilder ssb = new SearchSourceBuilder();
        
        //去重聚合
        CardinalityAggregationBuilder builder = AggregationBuilders.cardinality("distinct_color").field("color.keyword");
        
        ssb.aggregation(builder);
        request.source(ssb);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        Cardinality cardinality = search.getAggregations().get("distinct_color");
        System.out.println(cardinality.getValue());
    }

经验总结:看ES查询代码的聚合结构 即可构建出java代码。哪些桶嵌套在哪个桶内,重要的是搞清楚ES代码的结构!!!

欢迎各位到评论区交流,有什么不足和问题请多多指正哈!

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值