栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

10-ES的数据聚合

10-ES的数据聚合

数据聚合

**聚合(aggregations)**可以让我们极其方便的实现对数据的统计、分析、运算。

聚合的种类

聚合常见的有三类:

**桶(Bucket)**聚合:用来对文档做分组

TermAggregation:按照文档字段值分组,例如按照品牌值分组、按照国家分组Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组

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

Avg:求平均值Max:求最大值Min:求最小值Stats:同时求max、min、avg、sum等

**管道(pipeline)**聚合:其它聚合的结果为基础做聚合

**注意:**参加聚合的字段必须是keyword、日期、数值、布尔类型

DSL实现聚合 Bucket桶聚合语法

示例:

GET /hotel/_search
{
  "size": 0,  // 设置size为0,结果中不包含文档,只包含聚合结果
  "aggs": { // 定义聚合
    "brandAgg": { //给聚合起个名字
      "terms": { // 聚合的类型,按照品牌值聚合,所以选择term
        "field": "brand", // 参与聚合的字段
        "size": 20 // 希望获取的聚合结果数量
      }
    }
  }
}

结果:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 201,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "brandAgg" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 39,
      "buckets" : [
        {
          "key" : "7天酒店",
          "doc_count" : 30
        },
        {
          "key" : "如家",
          "doc_count" : 30
        },
        {
          "key" : "皇冠假日",
          "doc_count" : 17
        },
        {
          "key" : "速8",
          "doc_count" : 15
        },
        {
          "key" : "万怡",
          "doc_count" : 13
        },
        {
          "key" : "华美达",
          "doc_count" : 13
        },
        {
          "key" : "和颐",
          "doc_count" : 12
        },
        {
          "key" : "万豪",
          "doc_count" : 11
        },
        {
          "key" : "喜来登",
          "doc_count" : 11
        },
        {
          "key" : "希尔顿",
          "doc_count" : 10
        }
      ]
    }
  }
}
聚合结果排序

默认情况下,Bucket聚合会统计Bucket内的文档数量,记为_count,并且按照_count降序排序。

我们可以指定order属性,自定义聚合的排序方式:

GET /hotel/_search
{
  "size": 0, 
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "order": {
          "_count": "asc" // 按照_count升序排列
        },
        "size": 20
      }
    }
  }
}
限定聚合范围

默认情况下,Bucket聚合是对索引库的所有文档做聚合,但真实场景下,用户会输入搜索条件,因此聚合必须是对搜索结果聚合。那么聚合必须添加限定条件。

我们可以限定要聚合的文档范围,只要添加query条件即可:

GET /hotel/_search
{
  "query": {
    "range": {
      "price": {
        "lte": 200  // 只对200元以下的文档聚合
      }
    }
  },
  "size": 0,
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "order": {
          "_count": "asc"
        },
        "size": 20
      }
    }
  }
}

结果:

{
  "took" : 60,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 17,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "brandAgg" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "7天酒店",
          "doc_count" : 1
        },
        {
          "key" : "汉庭",
          "doc_count" : 1
        },
        {
          "key" : "速8",
          "doc_count" : 2
        },
        {
          "key" : "如家",
          "doc_count" : 13
        }
      ]
    }
  }
}
Metric聚合语法

stat聚合:就可以获取min、max、avg等结果。

语法如下:

GET /hotel/_search
{
  "size": 0,
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "order": {
          "_count": "asc"
        },
        "size": 20
      },
      "aggs": {// 是brands聚合的子聚合,也就是分组后对每组分别计算
        "scoreAgg": {// 聚合名称
          "stats": {// 聚合类型,这里stats可以计算min、max、avg等
            "field": "score"// 聚合字段,这里是score
          }
        }
      }
    }
  }
}

这次的score_stats聚合是在brandAgg的聚合内部嵌套的子聚合。因为我们需要在每个桶分别计算。

给聚合结果做个排序:

GET /hotel/_search
{
  "size": 0,
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "order": {
          "scoreAgg.avg": "desc"
        },
        "size": 20
      },
      "aggs": {
        "scoreAgg": {
          "stats": {
            "field": "score"
          }
        }
      }
    }
  }
}
小结

aggs代表聚合,与query同级,此时query的作用是?

限定聚合的的文档范围

聚合必须的三要素:

聚合名称聚合类型聚合字段

聚合可配置属性有:

size:指定聚合结果数量order:指定聚合结果排序方式field:指定聚合字段 RestClient实现聚合 API语法

聚合条件与query条件同级别,因此需要使用request.source()来指定聚合条件。

聚合条件的语法:

聚合的结果也与查询结果不同,API也比较特殊。不过同样是JSON逐层解析

示例代码
    @Test
    void testAggregation() 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 brandTerams = aggregations.get("brandAgg");
        //获取buckets
        List buckets = brandTerams.getBuckets();
        //遍历
        for (Terms.Bucket bucket : buckets) {
            //获取key
            String key = bucket.getKeyAsString();
            System.out.println(key);
        }
    }

    @BeforeEach
    void setUp() {
        client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.116.131:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException {
        client.close();
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/742548.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号