欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

10-ES的数据聚合

时间:2023-05-05
数据聚合

**聚合(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<? extends Terms.Bucket> 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(); }

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。