7.1 数据聚合

一、聚合的种类

  1. 聚合(aggregations),可以实现对文档数据的统计、分析、运算。聚合常见的有三类:

    1. 桶(Bucket)聚合:用来对文档做分组,常见的:

      1. TermAggregation:按照文档字段分组

      2. Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组

    2. 度量(Metric)聚合:用来计算一些值,比如:最大值、最小值、平均值等

      1. Avg:求平均值

      2. Max:求最大值

      3. Min:求最小值

      4. Stats:同时求max、min、avg、sum等

    3. 管道(pipeline)聚合:其他聚合的结果为基础做聚合

官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.14/search-aggregations.html

二、DSL实现聚合

  1. DSL实现Bucket聚合

    1. DSL示例:

      GET /索引库名称/_search
      {
          "size": 0,  // 设置size为0,结果中不会包含文档,只包含聚合结果
          "aggs": {  // 定义聚合
              "brandAgg": {  // 给一个聚合起个名字,自定义的
                  "term": {  // 聚合的类型,表示根据字段值做聚合
                      "field": "字段",  // 参与聚合的字段
                      "size": 20,  // 希望获取的聚合结果数量
                      "order": {   // 自定义排序规则,可以不加
                          "_count": "asc"
                      }
                  }
              }
          }
      }
    2. 默认情况下,Bucket聚合是对索引库的所有文档做聚合,我们可以限定要聚合的文档范围,只要添加query条件即可

      GET /索引库名称/_search
      {
          "query": {
              "range": {
                  "price": {    // 添加条件字段
                      "lte": 200   // 只对200元以下的文档聚合
                  }
              }
          },
          "size": 0,  // 设置size为0,结果中不会包含文档,只包含聚合结果
          "aggs": {  // 定义聚合
              "brandAgg": {  // 给一个聚合起个名字,自定义的
                  "term": {  // 聚合的类型,表示根据字段值做聚合
                      "field": "字段",  // 参与聚合的字段
                      "size": 20,  // 希望获取的聚合结果数量
                      "order": {   // 自定义排序规则,可以不加
                          "_count": "asc"
                      }
                  }
              }
          }
      }
  2. DSL实现Metrics聚合

    1. 示例

      GET /索引库名称/_search
      {
          "size": 0,  // 设置size为0,结果中不会包含文档,只包含聚合结果
          "aggs": {
              "brandAgg": {  // 给一个聚合起个名字,自定义的
                  "term": {  // 聚合的类型,表示根据字段值做聚合
                      "field": "字段",  // 参与聚合的字段
                      "size": 20,  // 希望获取的聚合结果数量
                      "order": {
                          "acoreAgg.avg": "asc"   // 根据下面的metrics聚合的avg结果进行排序
                      }
                  }
              }
          },
          "aggs": {   // 是brands聚合的子聚合,也就是分组后对每组分别计算
              "acoreAgg": {   // 聚合名称
                  "stats": {   // 聚合的类型,这里stats可以计算min、max、ave等
                      "fiels": "score"    // 聚合的字段
                  }
              }
          }
      }

三、RestAPI实现聚合

  1. RestAPI实现Bucket聚合

    // 请求组装
    request.source().size(0);
    request.source().aggregation(
    		AggregationBuilders.terms("brandAgg")   // DSL中给一个聚合起个名字
        					   .fiels("字段")       // 对那个字段进行聚合
        					   .size(20)            // 希望获取的聚合结果的数量
    );
        
    // 完整代码
        @Test
        public void aggregationTest() throws IOException {
            // 准备request
            SearchRequest request = new SearchRequest("hotel");
            // 准备DSL
            request.source().size(0);
            request.source().aggregation(
                    AggregationBuilders.terms("brandAgg")
                            .field("brand")
                            .size(20)
            );
            // 发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 解析结果
            Aggregations aggregations = response.getAggregations();
            // 根据聚合名称获取聚合结果
            Terms terms = aggregations.get("brandAgg");
            // 获取buckets
            List<? extends Terms.Bucket> buckets = terms.getBuckets();
            // 遍历
            for (Terms.Bucket bucket: buckets) {
                // 获取key
                String key = bucket.getKeyAsString();
                System.out.println(key);
            }
        }

最后更新于

这有帮助吗?