在信息检索和数据分析的世界中,我们常常需要做的不仅仅是找到匹配特定关键词的文档。很多时候,我们需要从海量数据中提取出更深层次的、有价值的洞察。例如:
这些问题都涉及对数据的统计和分析,而不仅仅是简单的搜索。为了满足这些需求,Elasticsearch 提供了强大的聚合查询(Aggregations) 功能。聚合查询就像一个多功能的瑞士军刀,或者说是一个强大的数据分析工具箱,它允许你对数据进行各种分组、统计和计算,从而提取出隐藏在数据背后的关键信息。
你可以把聚合查询想象成 SQL 中的 GROUP BY
子句和各种聚合函数(COUNT
, SUM
, AVG
, MIN
, MAX
)的组合,但 Elasticsearch 的聚合功能远比 SQL 更加灵活和强大。
本文将带你深入了解 Elasticsearch 7.10 版本中聚合查询的基础知识。通过本文,你将学习到:
avg
, min
, max
, sum
, stats
, value_count
, cardinality
)。terms
聚合进行分组。在开始学习聚合查询之前,我们需要先准备一些示例数据。我们将创建一个名为 product
的索引,并批量导入一些商品数据。
首先,我们创建一个名为 product
的索引,并定义其 mappings(映射)。Mappings 定义了索引中每个字段的数据类型以及如何进行索引和搜索。
PUT product
{
"mappings": {
"properties": {
"createtime": {
"type": "date"
},
"date": {
"type": "date"
},
"desc": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"lv": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"price": {
"type": "long"
},
"tags": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
接下来,我们使用 Elasticsearch 的 _bulk
API 来批量导入一些商品数据。_bulk
API 可以一次性执行多个索引、更新或删除操作,效率更高。
POST /product/_bulk
{"index":{"_index": "product"}}
{"name": "小米手机", "desc": "手机中的战斗机", "price": 3999, "lv": "旗舰机", "type": "手机", "createtime": "2020-10-01T08:00:00Z", "tags": [ "性价比", "发烧", "不卡顿" ]}
{"index":{"_index": "product"}}
{"name": "小米NFC手机", "desc": "支持全功能NFC,手机中的滑翔机", "price": 4999, "lv": "旗舰机", "type": "手机", "createtime": "2020-05-21T08:00:00Z", "tags": [ "性价比", "发烧", "公交卡" ]}
{"index":{"_index": "product"}}
{"name": "NFC手机", "desc": "手机中的轰炸机", "price": 2999, "lv": "高端机", "type": "手机", "createtime": "2020-06-20T08:00:00Z", "tags": [ "性价比", "快充", "门禁卡" ]}
{"index":{"_index": "product"}}
{"name": "小米耳机", "desc": "耳机中的黄焖鸡", "price": 999, "lv": "百元机", "type": "耳机", "createtime": "2020-06-23T08:00:00Z", "tags": [ "降噪", "防水", "蓝牙" ]}
{"index":{"_index": "product"}}
{"name": "红米耳机", "desc": "耳机中的肯德基", "price": 399, "type": "耳机", "lv": "百元机", "createtime": "2020-07-20T08:00:00Z", "tags": [ "防火", "低音炮", "听声辨位" ]}
{"index":{"_index": "product"}}
{"name": "小米手机10", "desc": "充电贼快掉电更快,超级无敌望远镜,高刷电竞屏", "price": null, "lv": "旗舰机", "type": "手机", "createtime": "2020-07-27T08:00:00Z", "tags": [ "120HZ刷新率", "120W快充", "120倍变焦" ]}
{"index":{"_index": "product"}}
{"name": "挨炮 SE2", "desc": "除了CPU,一无是处", "price": 3299, "lv": "旗舰机", "type": "手机", "createtime": "2020-07-21T08:00:00Z", "tags": [ "割韭菜", "割韭菜", "割新韭菜" ]}
{"index":{"_index": "product"}}
{"name": "XS Max", "desc": "听说要出新款12手机了,终于可以换掉手中的4S了", "price": 4399, "lv": "旗舰机", "type": "手机", "createtime": "2020-08-19T08:00:00Z", "tags": [ "5V1A", "4G全网通", "大" ]}
{"index":{"_index": "product"}}
{"name": "小米电视", "desc": "70寸性价比只选,不要一万八,要不要八千八,只要两千九百九十八", "price": 2998, "lv": "高端机", "type": "电视", "createtime": "2020-08-16T08:00:00Z", "tags": [ "巨馍", "家庭影院", "游戏" ]}
{"index":{"_index": "product"}}
{"name": "红米电视", "desc": "我比上边那个更划算,我也2998,我也70寸,但是我更好看", "price": 2999, "type": "电视", "lv": "高端机", "createtime": "2020-08-28T08:00:00Z", "tags": [ "大片", "蓝光8K", "超薄" ]}
{"index":{"_index": "product"}}
{"name": "红米电视", "desc": "我比上边那个更划算,我也2998,我也70寸,但是我更好看", "price": 2998, "type": "电视", "lv": "高端机", "createtime": "2020-08-28T08:00:00Z", "tags": [ "大片", "蓝光8K", "超薄" ]}
代码解释:
POST /product/_bulk
: 使用 _bulk
API 向 product
索引发送批量请求。现在,我们已经准备好了数据,可以开始学习 Elasticsearch 的聚合查询了!
聚合查询(Aggregations)是 Elasticsearch 中一种强大的数据分析功能,它允许你对文档数据进行各种统计分析。与搜索查询(返回匹配的文档)不同,聚合查询返回的是聚合后的统计结果。
你可以将聚合查询类比为 SQL 中的 GROUP BY
子句和聚合函数(如 COUNT
, SUM
, AVG
, MIN
, MAX
)。 例如,你可以使用 SQL 来计算每个部门的平均工资:
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
Elasticsearch 的聚合查询提供了类似的功能,但更加灵活和强大。它可以处理更复杂的数据结构和分析场景,并且可以进行多层嵌套的聚合。
聚合查询的基本语法结构如下:
GET /<index>/_search
{
"size": 0,
"aggs": {
"" : {
"" : {
""
},
"aggs": {
"" : {
"" : {
""
}
}
}
}
}
}
解释:
GET //_search
: 这是 Elasticsearch 的搜索 API,我们在这里使用它来执行聚合查询。"size": 0
: 这是一个可选参数。通常,在执行聚合查询时,我们只关心聚合结果,而不关心具体的文档内容。"size": 0
表示不返回任何文档,只返回聚合结果。"aggs"
(或 "aggregations"
): 这是聚合查询的顶层关键字。所有聚合操作都定义在 aggs
对象中。""
: 这是你为聚合操作指定的名称。这个名称可以是任意的,它将作为聚合结果的一部分返回,方便你识别和引用。例如,你可以将计算平均价格的聚合命名为 "avg_price"
。""
: 这是聚合的类型。Elasticsearch 提供了多种聚合类型,每种类型都有不同的功能。常见的聚合类型包括:
avg
(平均值)min
(最小值)max
(最大值)sum
(总和)terms
(词条聚合)stats
(统计信息)""
: 这是特定于聚合类型的参数。不同的聚合类型有不同的参数。例如,avg
聚合需要指定要计算平均值的字段,terms
聚合需要指定要分组的字段。"aggs": { ... }
(在
内部): 这是可选的嵌套聚合。你可以在一个聚合操作中嵌套另一个聚合操作,以实现更复杂的分析。例如,你可以先按产品类别分组,然后在每个类别中计算平均价格。Elasticsearch 提供了三种主要的聚合类型:
Metrics Aggregations (指标聚合): 这类聚合主要用于计算单个数值指标。例如:
avg
: 计算平均值。min
: 计算最小值。max
: 计算最大值。sum
: 计算总和。stats
: 一次性计算多个统计值(avg
, min
, max
, sum
, count
)。value_count
: 计算非空字段的文档数量。cardinality
: 计算字段的不同值的数量(去重)。Bucket Aggregations (桶聚合): 这类聚合主要用于将文档分组到不同的“桶”中。每个桶代表一个分组。例如:
terms
: 按字段值对文档进行分组。date_histogram
: 按日期范围对文档进行分组。range
: 按自定义数值范围对文档进行分组。filter
: 根据指定的过滤条件将文档分到一个桶filters
: 根据指定的多个过滤条件将文档分到多个桶Pipeline Aggregations (管道聚合): 这类聚合比较特殊,它们不直接操作文档,而是对其他聚合的结果进行进一步的聚合。例如:
min_bucket
: 找出包含最小值的桶。max_bucket
: 找出包含最大值的桶。avg_bucket
: 计算桶的平均值。sum_bucket
: 计算桶的总和。stats_bucket
: 对桶进行统计分析derivative
: 计算导数(例如,计算销售额的变化率)。本文将重点介绍这三种聚合类型的基础用法。接下来,我们将分别深入探讨每种聚合类型,并通过示例演示如何在实际应用中使用它们。
指标聚合用于计算单个数值指标,例如平均值、最小值、最大值、总和等。这些指标可以帮助你了解数据的整体特征。
avg
(平均值)avg
聚合用于计算指定字段的平均值。
示例: 计算 product
索引中所有产品的平均价格。
GET /product/_search
{
"size": 0,
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
代码解释:
"size": 0
: 不返回文档,只返回聚合结果。"aggs"
: 聚合查询的开始。"avg_price"
: 我们为这个聚合操作指定的名称。"avg"
: 指定聚合类型为 avg
(平均值)。"field": "price"
: 指定要计算平均值的字段为 price
。结果 (部分):
{
...
"aggregations": {
"avg_price": {
"value": 3008.8
}
}
}
结果中的 "value"
字段显示了所有产品价格的平均值。
min
(最小值)min
聚合用于计算指定字段的最小值。
示例: 计算 product
索引中所有产品的最低价格。
GET /product/_search
{
"size": 0,
"aggs": {
"min_price": {
"min": {
"field": "price"
}
}
}
}
结果 (部分):
{
...
"aggregations": {
"min_price": {
"value": 399.0
}
}
}
max
(最大值)max
聚合用于计算指定字段的最大值。
示例: 计算 product
索引中所有产品的最高价格。
GET /product/_search
{
"size": 0,
"aggs": {
"max_price": {
"max": {
"field": "price"
}
}
}
}
结果 (部分):
{
...
"aggregations": {
"max_price": {
"value": 4999.0
}
}
}
sum
(总和)sum
聚合用于计算指定字段的总和。
示例: 计算 product
索引中所有产品的价格总和。
GET /product/_search
{
"size": 0,
"aggs": {
"sum_price": {
"sum": {
"field": "price"
}
}
}
}
结果 (部分):
{
...
"aggregations": {
"sum_price": {
"value": 30088.0
}
}
}
stats
(统计信息)stats
聚合可以一次性计算多个统计值,包括:
count
: 文档数量。min
: 最小值。max
: 最大值。avg
: 平均值。sum
: 总和。示例: 获取 product
索引中所有产品的价格统计信息。
GET /product/_search
{
"size": 0,
"aggs": {
"price_stats": {
"stats": {
"field": "price"
}
}
}
}
结果 (部分):
{
...
"aggregations" : {
"statistics" : {
"count" : 10,
"min" : 399.0,
"max" : 4999.0,
"avg" : 3008.8,
"sum" : 30088.0
}
}
}
结果中一次性返回了count
,min
,max
,avg
和sum
value_count
(值计数)value_count
聚合用于计算指定字段的 非空 值的文档数量。
示例: 计算 product
索引中有多少个文档具有 price
字段(即有多少个产品有价格信息)。
GET /product/_search
{
"size": 0,
"aggs": {
"price_count": {
"value_count": {
"field": "price"
}
}
}
}
结果 (部分):
{
...
"aggregations": {
"price_count": {
"value": 10
}
}
}
注意,由于有一个文档的 price
字段为 null
,因此结果为 10,而不是 11。
cardinality
(基数/去重计数)cardinality
聚合用于计算指定字段的不同值的数量(即去重计数)。
示例: 计算 product
索引中有多少种不同的产品等级 (lv
)。
GET /product/_search
{
"size": 0,
"aggs": {
"lv_cardinality": {
"cardinality": {
"field": "lv.keyword"
}
}
}
}
代码解释:
"lv_cardinality"
: 聚合的名称。"cardinality"
: 指定聚合类型为 cardinality
。"field": "lv.keyword"
: 指定要计算基数的字段为 lv.keyword
。 这里使用 .keyword
子字段是因为我们要对原始的、未分词的 lv
值进行去重计数。结果 (部分):
{
...
"aggregations": {
"lv_cardinality": {
"value": 3
}
}
}
结果表明,product
索引中有 3 种不同的产品等级。
cardinality
聚合的计算结果是近似的,而不是完全精确的。对于低基数字段(即不同值较少),结果通常是准确的。但对于高基数字段(即不同值非常多),为了提高性能,Elasticsearch 使用了一种称为 HyperLogLog++ 的算法进行近似计算。你可以通过precision_threshold
参数来控制精度和内存使用之间的权衡。如果需要完全精确的去重计数,并且数据集较小,可以考虑使用terms
聚合,并设置一个足够大的size
值。但对于大数据集,cardinality
聚合通常是更好的选择。
桶聚合(Bucket Aggregations)用于将文档分组到不同的“桶”中。每个桶代表一个分组,可以根据不同的条件来创建桶。桶聚合本身不进行统计运算,其主要作用是分组。通常会在桶聚合内嵌套一个或者多个指标聚合,用于统计每个桶内的指标。
terms
(词条聚合)terms
聚合是最常用的桶聚合之一。它根据指定字段的值对文档进行分组,每个不同的字段值都会创建一个桶。
示例: 按 tags.keyword
字段对 product
索引中的产品进行分组,并统计每个标签下的文档数量。
GET /product/_search
{
"size": 0,
"aggs": {
"tag_bucket": {
"terms": {
"field": "tags.keyword",
"size": 10,
"order": {
"_count": "desc"
}
}
}
}
}
代码解释:
"size": 0
: 不返回文档,只返回聚合结果。"aggs"
: 聚合查询的开始。"tag_bucket"
: 我们为这个聚合操作指定的名称。"terms"
: 指定聚合类型为 terms
(词条聚合)。"field": "tags.keyword"
: 指定要进行分组的字段为 tags.keyword
。使用 .keyword
子字段是因为我们要基于标签的原始值进行分组,而不是分词后的结果。"size": 10
: 指定返回的桶的最大数量。默认情况下,terms
聚合会返回文档数量最多的前 10 个桶。"order": { "_count": "desc" }
: 指定桶的排序方式。这里按照每个桶中文档数量 (_count
) 的降序 (desc
) 进行排序。结果(部分):
{
...
"aggregations": {
"tag_bucket": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 8,
"buckets": [
{
"key": "性价比",
"doc_count": 3
},
{
"key": "发烧",
"doc_count": 2
},
{
"key": "大片",
"doc_count": 2
},
{
"key": "蓝光8K",
"doc_count": 2
},
{
"key": "超薄",
"doc_count": 2
},
{
"key": "割韭菜",
"doc_count": 2
},
{
"key": "120W快充",
"doc_count": 1
},
{
"key": "120HZ刷新率",
"doc_count": 1
},
{
"key": "120倍变焦",
"doc_count": 1
},
{
"key": "4G全网通",
"doc_count": 1
}
]
}
}
}
结果解释:
"buckets"
: 这是一个数组,包含了根据 tags.keyword
字段值分组后的桶。"key"
: 每个桶的键,即 tags.keyword
字段的值(例如 “性价比”, “发烧”)。"doc_count"
: 每个桶中的文档数量。"doc_count_error_upper_bound"
:由于terms
聚合默认情况下返回文档数量最多的前N个桶,这个值表示因为桶数量限制,没有被统计到的文档数量的最大可能误差值。"sum_other_doc_count"
: 由于terms
聚合默认情况下返回文档数量最多的前N个桶,这个值表示未返回的其他桶中文档数量的总和。size
参数:
size
参数控制返回的桶的数量。 如果你想返回所有桶,可以将 size
设置为一个较大的值(例如,大于字段中不同值的数量)。 但是,请注意,如果字段的基数非常高(即有很多不同的值),返回所有桶可能会消耗大量内存。
order
参数:
order
参数控制桶的排序方式。除了按 _count
排序外,还可以:
_key
排序:"order": { "_key": "asc" }
(按字段值升序) 或 "order": { "_key": "desc" }
(按字段值降序)。在实际应用中,我们经常需要进行多层级的聚合。例如,我们想先按type
进行分组,然后统计每个type
中price
的平均值。这种情况下我们就需要用到嵌套聚合。
GET /product/_search
{
"size": 0,
"aggs": {
"type_bucket": {
"terms": {
"field": "type.keyword"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
代码解释:
terms
聚合, 根据type.keyword
字段进行分组。avg
聚合, 计算每个分组内price
字段的平均值。结果(部分):
{
...
"aggregations": {
"type_bucket": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key" : "手机",
"doc_count" : 6,
"avg_price" : {
"value" : 3939.0
}
},
{
"key" : "耳机",
"doc_count" : 3,
"avg_price" : {
"value" : 1465.3333333333333
}
},
{
"key" : "电视",
"doc_count" : 2,
"avg_price" : {
"value" : 2998.5
}
}
]
}
}
}
结果解释:
"buckets"
: 这是一个数组,包含了根据 type.keyword
字段值分组后的桶。"key"
: 每个桶的键,即 type.keyword
字段的值(例如 “手机”, “耳机”)。"doc_count"
: 每个桶中的文档数量。"avg_price"
: 每个桶中嵌套聚合的结果, 即该类型商品的平均价格。通过嵌套聚合,我们可以轻松实现多层级的数据分析。我们可以根据需求自由组合不同的聚合类型,构建出非常复杂的聚合查询。
管道聚合(Pipeline Aggregations)是一种特殊的聚合类型。它们不像指标聚合和桶聚合那样直接操作文档,而是对其他聚合的结果进行进一步的聚合。这就像在数据处理流程中添加了一个额外的“管道”,对上游聚合的输出进行处理。
管道聚合的核心思想是:输入是另一个聚合(或多个聚合)的输出,而不是文档本身。这使得我们可以进行诸如以下操作:
管道聚合的关键参数是 buckets_path
,它用于指定要作为输入的聚合的路径。
min_bucket
(最小桶)min_bucket
管道聚合用于找出包含最小值的桶。
示例: 找出平均价格最低的产品分类(基于之前嵌套聚合的结果)。
GET /product/_search
{
"size": 0,
"aggs": {
"type_bucket": {
"terms": {
"field": "type.keyword"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
},
"min_avg_price_bucket": {
"min_bucket": {
"buckets_path": "type_bucket>avg_price"
}
}
}
}
代码解释:
"type_bucket"
: 这是一个 terms
聚合,按产品类型 (type.keyword
) 分组。"avg_price"
: 这是一个嵌套的 avg
聚合,计算每个产品类型的平均价格。"min_avg_price_bucket"
: 这是我们定义的管道聚合的名称。"min_bucket"
: 指定聚合类型为 min_bucket
。"buckets_path": "type_bucket>avg_price"
: 这是 buckets_path
参数,它指定了要处理的聚合路径。
type_bucket
: 表示外层的 terms
聚合。>
: 表示嵌套关系。avg_price
: 表示内层的 avg
聚合。"type_bucket>avg_price"
表示我们要找到 type_bucket
聚合中,avg_price
聚合结果最小的那个桶。结果(部分):
{
...
"aggregations": {
"type_bucket": {
... // 省略了 type_bucket 的详细结果
},
"min_avg_price_bucket": {
"value": 1465.3333333333333,
"keys": [
"耳机"
]
}
}
}
结果解释:
"min_avg_price_bucket"
: 管道聚合的结果。"value"
: 最小值 (最低的平均价格)。"keys"
: 取得最小值的桶的key
值数组, 在本例中, 平均价格最低的分类是 “耳机”。除了 min_bucket
之外,ElasticSearch 还提供了其他几种管道聚合:
max_bucket
: 找出包含最大值的桶。用法与min_bucket
类似, 只是找出最大值。avg_bucket
: 计算所有桶中某个指标的平均值。sum_bucket
: 计算所有桶中某个指标的总和。stats_bucket
:一次性计算多个统计值, 类似于stats
指标聚合, 但是stats_bucket
是作用于桶聚合的结果之上。derivative
: 计算导数(例如,计算销售额的变化率)。moving_avg
: 计算移动平均值(例如,计算过去 7 天的平均销售额)。bucket_script
: 使用脚本对桶的指标进行自定义计算。bucket_selector
: 根据脚本过滤桶。bucket_sort
: 对桶进行排序。这些管道聚合提供了更高级的数据分析功能。你可以在 ElasticSearch 的官方文档中找到关于它们的详细信息。
现在,让我们通过几个更贴近实际应用的示例,来展示如何组合不同类型的聚合,以解决真实的数据分析问题。
这个案例结合了 terms
桶聚合、max
指标聚合和排序。
GET product/_search
{
"size": 0,
"aggs": {
"type_bucket": {
"terms": {
"field": "type.keyword",
"order": {
"max_price": "desc"
}
},
"aggs": {
"max_price": {
"max": {
"field": "price"
}
}
}
}
}
}
代码解释:
"type_buckets"
: terms
聚合,按 type.keyword
字段(产品类型)分组。"order": { "max_price": "desc" }
: 按嵌套的 max_price
聚合的结果(即每个类别中的最高价格)进行降序排序。"max_price"
: 嵌套的 max
聚合,计算每个类别中的最高价格。结果(部分):
{
...
"aggregations": {
"type_buckets": {
...
"buckets": [
{
"key" : "手机",
"doc_count" : 6,
"max_price" : {
"value" : 4999.0
}
},
{
"key" : "电视",
"doc_count" : 2,
"max_price" : {
"value" : 2999.0
}
},
{
"key" : "耳机",
"doc_count" : 3,
"max_price" : {
"value" : 2998.0
}
}
]
}
}
}
这个案例结合了 date_histogram
桶聚合、sum
指标聚合和 max_bucket
管道聚合。
GET /product/_search
{
"size": 0,
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "createtime",
"calendar_interval": "month"
},
"aggs": {
"sales_per_day": {
"date_histogram": {
"field": "createtime",
"calendar_interval": "day"
},
"aggs": {
"daily_sales": {
"sum": {
"field": "price"
}
}
}
},
"max_daily_sales": {
"max_bucket": {
"buckets_path": "sales_per_day>daily_sales"
}
}
}
}
}
}
代码解释:
sales_per_month
(外层 date_histogram
):
"calendar_interval": "month"
)。field
: “createtime”sales_per_day
(内层 date_histogram
):
"calendar_interval": "day"
)。field
: “createtime”daily_sales
(指标聚合):
"sum": { "field": "price" }
)。max_daily_sales
(管道聚合):
max_bucket
管道聚合。"buckets_path": "sales_per_day>daily_sales"
: 找出每个月内,daily_sales
(销售总额) 最高的那个 sales_per_day
(天) 桶。结果 (部分):
{
...
"aggregations": {
"sales_per_month": {
"buckets": [
{
"key_as_string": "2020-05-01T00:00:00.000Z",
"key": 1588291200000,
"doc_count": 1,
"sales_per_day": {
...
},
"max_daily_sales": {
"value": 4999.0,
"keys": [
"2020-05-21T00:00:00.000Z"
]
}
},
{
"key_as_string": "2020-06-01T00:00:00.000Z",
"key": 1590969600000,
"doc_count": 2,
"sales_per_day": {
...
},
"max_daily_sales": {
"value": 2999.0,
"keys": [
"2020-06-20T00:00:00.000Z"
]
}
},
...
]
}
}
}
结果显示, 对于每个月, 销售额最高的那一天的日期和销售额都被找了出来. 例如, 在2020年5月, 销售额最高的那一天是2020-05-21, 销售额是4999.
这两个案例展示了如何将不同类型的聚合组合起来,以解决更复杂的数据分析问题。 ElasticSearch 聚合的强大之处在于其灵活性和可组合性,你可以根据自己的需求设计出各种各样的聚合查询。\
在本教程中,我们深入探讨了 Elasticsearch 7.10 中聚合查询的基础知识。聚合查询是 Elasticsearch 中进行数据分析的强大工具,它能够帮助你从海量数据中提取出有价值的统计信息和洞察。
我们学习了:
avg
, min
, max
, sum
, stats
, value_count
, cardinality
, terms
, min_bucket
, max_bucket
等。Elasticsearch 的聚合功能远不止于此。本文只是一个入门指南,涵盖了最基础和最常用的部分。要充分发挥 Elasticsearch 聚合的威力,你需要不断学习和实践,探索更高级的聚合类型和用法。
进一步学习的建议:
date_histogram
、range
、filters
、geo_distance
、percentiles
、top_hits
等等。希望本文能帮助你入门 Elasticsearch 聚合查询。祝你在数据分析的道路上不断进步!