ElasticSearch Aggregation(七)

2024-02-27 16:58
文章标签 elasticsearch aggregation

本文主要是介绍ElasticSearch Aggregation(七),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • ElasticSearch Aggregation(七)
    • 管道聚合
      • average bucket聚合
        • 语法
        • 参数
        • 响应体
        • 例子
      • bucket script聚合
        • 语法
      • bucket selector聚合
        • 语法
      • bucket sort聚合
        • 语法
        • 截断而不进行排序
      • cumulative cardinality聚合
        • 语法
        • 增量累积基数聚合

ElasticSearch Aggregation(七)

管道聚合

管道聚合作用于其他聚合后的结果上,而不是作用于文档集合。有很多不同类型的管道聚合,每一种都会根据其他聚合数据计算出不同的信息,但是这些类型可以分为两种家族:

  • Parent:一系列管道聚合,随其父聚合的输出一起提供,并且能够计算新存储桶或新聚合以添加到现有存储桶。
  • Sibling:管道聚合随同级聚合的输出一起提供,并且能够计算与同级聚合处于同一级别的新聚合。

管道聚合通过bucket_path参数来指定所需聚合的路径。定义bucket_path参数可以通过bucket_path语法来定义

管道聚合不能有子聚合,但根据类型,它可以引用 buckets_path 中的另一个管道,允许链接管道聚合。

提示:由于管道聚合仅添加到输出,因此在链接管道聚合时,每个管道聚合的输出将包含在最终输出中。

bucket_path语法

大多数管道聚合要求其他的聚合作为他的输入。输入的定义通过bucket_path参数来定义,可以根据以下格式来定义bucket_path参数:

AGG_SEPARATOR       =  `>` ;
METRIC_SEPARATOR    =  `.` ;
AGG_NAME            =  <the name of the aggregation> ;
METRIC              =  <the name of the metric (in case of multi-value metrics aggregation)> ;
MULTIBUCKET_KEY     =  `[<KEY_NAME>]`
PATH                =  <AGG_NAME><MULTIBUCKET_KEY>? (<AGG_SEPARATOR>, <AGG_NAME> )* ( <METRIC_SEPARATOR>, <METRIC> ) ;

例如,路径my_bucket>my_stats.avg将指向my_stats指标中的avg聚合值,该指标将会包含在my_bucket桶聚合中。

管道聚合的路径是相对的,不是绝对路径。例如移动平均数被嵌入到日期直方图的内部,并且引用一个兄弟指标the_sum

curl -X POST "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{"aggs": {"my_date_histo": {"date_histogram": {"field": "timestamp","calendar_interval": "day"},"aggs": {"the_sum": {"sum": { "field": "lemmings" } },"the_movavg": {"moving_avg": { "buckets_path": "the_sum" } }}}}
}
'

以上例子目的是在每个聚合桶中对the_sum指标进行moving avg操作。

bucket_path也可以在兄弟管道聚合中使用。

curl -X POST "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{"aggs": {"sales_per_month": {"date_histogram": {"field": "date","calendar_interval": "month"},"aggs": {"sales": {"sum": {"field": "price"}}}},"max_monthly_sales": {"max_bucket": {"buckets_path": "sales_per_month>sales" }}}
}
'

bucket_path指示在date_per_month数据直方图中后去sales聚合的最大值。

如果兄弟管道聚合引用了一个多桶聚合,例如terms聚合,可以在多桶中选择特定的键。例如bucket_script可以选择特定的桶执行计算:

curl -X POST "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{"aggs": {"sales_per_month": {"date_histogram": {"field": "date","calendar_interval": "month"},"aggs": {"sale_type": {"terms": {"field": "type"},"aggs": {"sales": {"sum": {"field": "price"}}}},"hat_vs_bag_ratio": {"bucket_script": {"buckets_path": {"hats": "sale_type['hat']>sales",   "bags": "sale_type['bag']>sales"    },"script": "params.hats / params.bags"}}}}}
}
'

特殊的路径

buckets_path可以使用一个特殊的_count路径,而不是一个指标路径。这意味着管道聚合使用文档数量作为其输入。例如,移动平均数可以根据每个桶的文档数量来计算,而不是一个特定的指标:

curl -X POST "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{"aggs": {"my_date_histo": {"date_histogram": {"field": "timestamp","calendar_interval": "day"},"aggs": {"the_movavg": {"moving_avg": { "buckets_path": "_count" } }}}}
}
'

average bucket聚合

平均桶聚合。同级管道聚合,用于计算同级聚合中指定指标的平均值。指定的指标必须是数字,同级聚合必须是多桶聚合。

语法
"avg_bucket": {"buckets_path": "sales_per_month>sales","gap_policy": "skip","format": "#,##0.00;(#,##0.00)"
}
参数
  • bucket_path:(必须,String),平均计算所需的桶路径
  • gep_policy:(可选,string),在数据中发现间距对应的处理策略。默认为skip
  • format:(可选的,String),输出的DecimalFormat模式的值。如果指定,将会在聚合的value_as_string属性中返回被格式化的值。
响应体
  • value:(flat),bucket_path指定的路径指标的平均值
  • value_as_string:(string),聚合的格式化输出值。只有在请求中指定了格式时才提供此属性。
例子

根据avg_monthly_sales聚合使用avg_bucket来计算每个月sales的平均值

curl -X POST "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{"size": 0,"aggs": {"sales_per_month": {"date_histogram": {"field": "date","calendar_interval": "month"},"aggs": {"sales": {"sum": {"field": "price"}}}},"avg_monthly_sales": {             "avg_bucket": {"buckets_path": "sales_per_month>sales","gap_policy": "skip","format": "#,##0.00;(#,##0.00)"}             }}
}
'

响应:

{"took": 11,"timed_out": false,"_shards": ...,"hits": ...,"aggregations": {"sales_per_month": {"buckets": [{"key_as_string": "2015/01/01 00:00:00","key": 1420070400000,"doc_count": 3,"sales": {"value": 550.0}},{"key_as_string": "2015/02/01 00:00:00","key": 1422748800000,"doc_count": 2,"sales": {"value": 60.0}},{"key_as_string": "2015/03/01 00:00:00","key": 1425168000000,"doc_count": 2,"sales": {"value": 375.0}}]},"avg_monthly_sales": {"value": 328.33333333333333,"value_as_string": "328.33"}}
}

bucket script聚合

可以执行脚本的父管道聚合,这个脚本可以在每个桶中单独执行。

语法
{"bucket_script": {"buckets_path": {"my_var1": "the_sum",                     "my_var2": "the_value_count"},"script": "params.my_var1 / params.my_var2"}
}

以下代码段计算了 T 恤销售额与每月总销售额的比率百分比:

curl -X POST "localhost:9200/sales/_search?pretty" -H 'Content-Type: application/json' -d'
{"size": 0,"aggs": {"sales_per_month": {"date_histogram": {"field": "date","calendar_interval": "month"},"aggs": {"total_sales": {"sum": {"field": "price"}},"t-shirts": {"filter": {"term": {"type": "t-shirt"}},"aggs": {"sales": {"sum": {"field": "price"}}}},"t-shirt-percentage": {"bucket_script": {"buckets_path": {"tShirtSales": "t-shirts>sales","totalSales": "total_sales"},"script": "params.tShirtSales / params.totalSales * 100"}}}}}
}
'

响应:

{"took": 11,"timed_out": false,"_shards": ...,"hits": ...,"aggregations": {"sales_per_month": {"buckets": [{"key_as_string": "2015/01/01 00:00:00","key": 1420070400000,"doc_count": 3,"total_sales": {"value": 550.0},"t-shirts": {"doc_count": 1,"sales": {"value": 200.0}},"t-shirt-percentage": {"value": 36.36363636363637}},{"key_as_string": "2015/02/01 00:00:00","key": 1422748800000,"doc_count": 2,"total_sales": {"value": 60.0},"t-shirts": {"doc_count": 1,"sales": {"value": 10.0}},"t-shirt-percentage": {"value": 16.666666666666664}},{"key_as_string": "2015/03/01 00:00:00","key": 1425168000000,"doc_count": 2,"total_sales": {"value": 375.0},"t-shirts": {"doc_count": 1,"sales": {"value": 175.0}},"t-shirt-percentage": {"value": 46.666666666666664}}]}}
}

bucket selector聚合

执行脚本的父管道聚合,该脚本确定当前存储桶是否将保留在父多存储桶聚合中。指定的指标必须是数字,并且脚本必须返回布尔值。如果脚本语言是表达式,则允许使用数字返回值。在这种情况下,0.0将被计算为false,而所有其他值将被计算为true

提示:与所有管道聚合一样,bucket_selector聚合在所有其他同级聚合之后执行。这意味着使用bucket_selector聚合来过滤响应中返回的桶并不会节省运行聚合的执行时间。

语法
{"bucket_selector": {"buckets_path": {"my_var1": "the_sum",                     "my_var2": "the_value_count"},"script": "params.my_var1 > params.my_var2"}
}

以下代码段仅保留当月总销售额超过 200 的存储桶:

curl -X POST "localhost:9200/sales/_search?pretty" -H 'Content-Type: application/json' -d'
{"size": 0,"aggs": {"sales_per_month": {"date_histogram": {"field": "date","calendar_interval": "month"},"aggs": {"total_sales": {"sum": {"field": "price"}},"sales_bucket_filter": {"bucket_selector": {"buckets_path": {"totalSales": "total_sales"},"script": "params.totalSales > 200"}}}}}
}
'

响应:

{"took": 11,"timed_out": false,"_shards": ...,"hits": ...,"aggregations": {"sales_per_month": {"buckets": [{"key_as_string": "2015/01/01 00:00:00","key": 1420070400000,"doc_count": 3,"total_sales": {"value": 550.0}},{"key_as_string": "2015/03/01 00:00:00","key": 1425168000000,"doc_count": 2,"total_sales": {"value": 375.0},}]}}
}

bucket sort聚合

父管道聚合,这聚合对父多桶聚合的结果进行排序。可以指定0个或者多个字段进行排序。每一个桶可能根据_key或者_count或者子聚合进行排序。此外,可以设置参数 fromsize 以截断结果桶。

提示:与所有管道聚合一样,bucket_sort 聚合在所有其他非管道聚合之后执行。这意味着排序仅适用于已从父聚合返回的任何桶。例如,如果父聚合是 term 并且其大小设置为 10,bucket_sort 将仅对这 10 个返回的 term 桶进行排序。

语法

bucket_sort 聚合如下所示:

{"bucket_sort": {"sort": [{ "sort_field_1": { "order": "asc" } },   { "sort_field_2": { "order": "desc" } },"sort_field_3"],"from": 1,"size": 3}
}

下面的代码片段按降序返回总销售额最高的3个月对应的桶:

curl -X POST "localhost:9200/sales/_search?pretty" -H 'Content-Type: application/json' -d'
{"size": 0,"aggs": {"sales_per_month": {"date_histogram": {"field": "date","calendar_interval": "month"},"aggs": {"total_sales": {"sum": {"field": "price"}},"sales_bucket_sort": {"bucket_sort": {"sort": [{ "total_sales": { "order": "desc" } } ],"size": 3                                }}}}}
}
'

响应:

{"took": 82,"timed_out": false,"_shards": ...,"hits": ...,"aggregations": {"sales_per_month": {"buckets": [{"key_as_string": "2015/01/01 00:00:00","key": 1420070400000,"doc_count": 3,"total_sales": {"value": 550.0}},{"key_as_string": "2015/03/01 00:00:00","key": 1425168000000,"doc_count": 2,"total_sales": {"value": 375.0},},{"key_as_string": "2015/02/01 00:00:00","key": 1422748800000,"doc_count": 2,"total_sales": {"value": 60.0},}]}}
}
截断而不进行排序

你可能使用这个聚合来截断结果桶而不进行任何排序。为此你只需要设置fromsize参数,而不设置sort参数就可以达到这个效果

curl -X POST "localhost:9200/sales/_search?pretty" -H 'Content-Type: application/json' -d'
{"size": 0,"aggs": {"sales_per_month": {"date_histogram": {"field": "date","calendar_interval": "month"},"aggs": {"bucket_truncate": {"bucket_sort": {"from": 1,"size": 1}}}}}
}
'

响应:

{"took": 11,"timed_out": false,"_shards": ...,"hits": ...,"aggregations": {"sales_per_month": {"buckets": [{"key_as_string": "2015/02/01 00:00:00","key": 1422748800000,"doc_count": 2}]}}
}

cumulative cardinality聚合

累积基数聚合。累积基数聚合是一个父管道聚合,该聚合在父直方图聚合中计算累积基数。指定的指标必须是一个基数聚合并且外围的直方图必须设置min_doc_count0

cumulative_cardinality聚合对于发现总的新条目非常有用,可以理解为每天新访问你web网站的用户数量。常规的基数聚合只会告诉你每天有多少个唯一的访问用户,但是他不会区分新用户或者重复用户。累积基数聚合可用于确定每天有多少独立访问者是“新”访问者。

语法

cumulative_cardinality 聚合看起来像这样:

{"cumulative_cardinality": {"buckets_path": "my_cardinality_agg"}
}

以下代码段计算每日总用户的累积基数:

curl -X GET "localhost:9200/user_hits/_search?pretty" -H 'Content-Type: application/json' -d'
{"size": 0,"aggs": {"users_per_day": {"date_histogram": {"field": "timestamp","calendar_interval": "day"},"aggs": {"distinct_users": {"cardinality": {"field": "user_id"}},"total_new_users": {"cumulative_cardinality": {"buckets_path": "distinct_users" }}}}}
}
'

以下可能是响应:

{"took": 11,"timed_out": false,"_shards": ...,"hits": ...,"aggregations": {"users_per_day": {"buckets": [{"key_as_string": "2019-01-01T00:00:00.000Z","key": 1546300800000,"doc_count": 2,"distinct_users": {"value": 2},"total_new_users": {"value": 2}},{"key_as_string": "2019-01-02T00:00:00.000Z","key": 1546387200000,"doc_count": 2,"distinct_users": {"value": 2},"total_new_users": {"value": 3}},{"key_as_string": "2019-01-03T00:00:00.000Z","key": 1546473600000,"doc_count": 3,"distinct_users": {"value": 3},"total_new_users": {"value": 4}}]}}
}

注意第二天,2019-01-02,有两个不同的用户,但是累积管道agg生成的total_new_users指标只增加到3。这意味着当天的两个用户中只有一个是新用户,另一个在前一天已经被看到过。这种情况会在第三天再次发生,即三个用户中只有一个是全新的。

增量累积基数聚合

cumulative_cardinality 聚合将向您显示查询时间段开始以来的总数、不同的计数。然而,有时查看“增量”数量是有用的。意思是每天新增多少用户,而不是累计总数。

这可以通过向我们的查询添加derivative聚合来实现:

curl -X GET "localhost:9200/user_hits/_search?pretty" -H 'Content-Type: application/json' -d'
{"size": 0,"aggs": {"users_per_day": {"date_histogram": {"field": "timestamp","calendar_interval": "day"},"aggs": {"distinct_users": {"cardinality": {"field": "user_id"}},"total_new_users": {"cumulative_cardinality": {"buckets_path": "distinct_users"}},"incremental_new_users": {"derivative": {"buckets_path": "total_new_users"}}}}}
}
'

以下可能是响应:

{"took": 11,"timed_out": false,"_shards": ...,"hits": ...,"aggregations": {"users_per_day": {"buckets": [{"key_as_string": "2019-01-01T00:00:00.000Z","key": 1546300800000,"doc_count": 2,"distinct_users": {"value": 2},"total_new_users": {"value": 2}},{"key_as_string": "2019-01-02T00:00:00.000Z","key": 1546387200000,"doc_count": 2,"distinct_users": {"value": 2},"total_new_users": {"value": 3},"incremental_new_users": {"value": 1.0}},{"key_as_string": "2019-01-03T00:00:00.000Z","key": 1546473600000,"doc_count": 3,"distinct_users": {"value": 3},"total_new_users": {"value": 4},"incremental_new_users": {"value": 1.0}}]}}
}

这篇关于ElasticSearch Aggregation(七)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/753049

相关文章

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

ElasticSearch的DSL查询⑤(ES数据聚合、DSL语法数据聚合、RestClient数据聚合)

目录 一、数据聚合 1.1 DSL实现聚合 1.1.1 Bucket聚合  1.1.2 带条件聚合 1.1.3 Metric聚合 1.1.4 总结 2.1 RestClient实现聚合 2.1.1 Bucket聚合 2.1.2 带条件聚合 2.2.3 Metric聚合 一、数据聚合 聚合(aggregations)可以让我们极其方便的实现对数据的统计、分析、运算。例如:

【docker】基于docker-compose 安装elasticsearch + kibana + ik分词器(8.10.4版本)

记录下,使用 docker-compose 安装 Elasticsearch 和 Kibana,并配置 IK 分词器,你可以按照以下步骤进行。此过程适用于 Elasticsearch 和 Kibana 8.10.4 版本。 安装 首先,在你的工作目录下创建一个 docker-compose.yml 文件,用于配置 Elasticsearch 和 Kibana 的服务。 version:

ElasticSearch底层原理简析

1.ElasticSearch简述 ElastiaSearch(以下简称ES)是一个基于Lucene的搜索服务器,它提供了一个分布式多用户能力的全文搜索引擎,支持RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。ES设计用于云计算中,能够进行实时搜索,支持PB级搜索,具有稳定,可靠,快速,安装使用方便等

ElasticSearch 6.1.1 通过Head插件,新建索引,添加文档,及其查询数据

ElasticSearch 6.1.1 通过Head插件,新建索引,添加文档,及其查询; 一、首先启动相关服务: 二、新建一个film索引: 三、建立映射: 1、通过Head插件: POST http://192.168.1.111:9200/film/_mapping/dongzuo/ {"properties": {"title": {"type":

ElasticSearch 6.1.1运用代码添加索引及其添加,修改,删除文档

1、新建一个MAVEN项目:ElasticSearchTest 2、修改pom.xml文件内容: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.or

Windows下安装Elasticsearch,启动报错,解决方法,访问

对于Windows用户,我们推荐使用MSI安装包进行安装。这个安装包使用图形用户界面来引导你进行安装。 首先,从这里https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.1.1.msi下载Elasticsearch 6.1.1的MSI安装包。 然后双击下载好的安装包文件启动图形化安装程序,在第一个界面,选

Elasticsearch:无状态世界中的数据安全

作者:来自 Elastic Henning Andersen 在最近的博客文章中,我们宣布了支持 Elastic Cloud Serverless 产品的无状态架构。通过将持久性保证和复制卸载到对象存储(例如 Amazon S3),我们获得了许多优势和简化。 从历史上看,Elasticsearch 依靠本地磁盘持久性来确保数据安全并处理陈旧或孤立的节点。在本博客中,我们将讨论无状态的数据持

ElasticSearch的DSL查询④(DSL查询、RestClient的DSL查询)

目录 一、DSL查询 1.1 快熟入门 1.2 叶子查询 1.2.1 全文检索查询 1)match查询 2)multi_match查询 1.2.2 精确查询 1)term查询 2)range查询 3)ids查询 1.3 复合查询 1.3.1 bool查询 1.3.2 算分函数查询 1)基本语法: 2)运行流程: 3)示例: 4)执行结果: 1.4 排序 1.5

Mac使用Elasticsearch

下载 Past Releases of Elastic Stack Software | Elastic 解压tar -xzvf elasticsearch-8.15.1-darwin-x86_64.tar.gz  修改配置文件config/elasticsearch.yml xpack.security.enabled: false xpack.security.http.