“ElasticSearch聚合分析:分桶聚合(bucket)”的版本间差异
		
		
		
		
		
		跳到导航
		跳到搜索
		
				
		
		
	
小 (Eijux移动页面ElasticSearch聚合分析:分组聚合查询(bucket)至ElasticSearch聚合分析:分桶聚合(bucket),不留重定向)  | 
				无编辑摘要  | 
				||
| 第14行: | 第14行: | ||
* '''Histogram 聚合''':根据'''数值间隔'''分组;  | * '''Histogram 聚合''':根据'''数值间隔'''分组;  | ||
*: 例如: 价格按100间隔分组,0、100、200、300等等  | *: 例如: 价格按100间隔分组,0、100、200、300等等  | ||
* '''Date   | * '''Date histogram 聚合''':根据时间间隔分组;  | ||
*: 例如:按月、按天、按小时分组  | *: 例如:按月、按天、按小时分组  | ||
* '''  | * '''Range 聚合''':按数值范围分组;  | ||
*: 例如: 0-150一组,150-200一组,200-500一组。  | *: 例如: 0-150一组,150-200一组,200-500一组。  | ||
| 第22行: | 第22行: | ||
* “桶聚合”一般不单独使用,都是配合“指标聚合”一起使用,对数据分组之后肯定要统计桶内数据,在 ES 中如果没有明确指定指标聚合,默认使用 '''Value Count''' 指标聚合,统计桶内文档总数。  | * “桶聚合”一般不单独使用,都是配合“指标聚合”一起使用,对数据分组之后肯定要统计桶内数据,在 ES 中如果没有明确指定指标聚合,默认使用 '''Value Count''' 指标聚合,统计桶内文档总数。  | ||
== Terms 聚合 ==  | |||
terms 聚合的作用跟 SQL 中 group by 作用一样,都是根据字段唯一值对数据进行分组(分桶),字段值相等的文档都分到同一个桶内。  | |||
示例:  | |||
<syntaxhighlight lang="JSON" highlight="">  | |||
GET /order/_search?size=0  | |||
{  | |||
  "aggs": {  | |||
    "shop": { // 聚合查询的名字,随便取个名字  | |||
      "terms": { // 聚合类型为: terms  | |||
        "field": "shop_id" // 根据shop_id字段值,分桶  | |||
      }  | |||
    }  | |||
  }  | |||
}  | |||
</syntaxhighlight>  | |||
等级SQL:  | |||
<syntaxhighlight lang="SQL" highlight="">  | |||
select shop_id, count(*) from order group by shop_id  | |||
</syntaxhighlight>  | |||
返回结果:  | |||
<syntaxhighlight lang="JSON" highlight="">  | |||
{  | |||
    ...  | |||
    "aggregations" : {  | |||
        "shop" : { // 聚合查询名字  | |||
            "buckets" : [ // 桶聚合结果,下面返回各个桶的聚合结果  | |||
                {  | |||
                    "key" : "1", // key分桶的标识,在terms聚合中,代表的就是分桶的字段值  | |||
                    "doc_count" : 6 // 默认的指标聚合是统计桶内文档总数  | |||
                },  | |||
                {  | |||
                    "key" : "5",  | |||
                    "doc_count" : 3  | |||
                },  | |||
                {  | |||
                    "key" : "9",  | |||
                    "doc_count" : 2  | |||
                }  | |||
            ]  | |||
        }  | |||
    }  | |||
}  | |||
</syntaxhighlight>  | |||
== Histogram 聚合 ==  | |||
histogram(直方图)聚合,主要根据数值间隔分组,使用 histogram 聚合分桶统计结果,通常用在绘制条形图报表。  | |||
示例:  | |||
<syntaxhighlight lang="JSON" highlight="">  | |||
POST /sales/_search?size=0  | |||
{  | |||
    "aggs" : {  | |||
        "prices" : { // 聚合查询名字,随便取一个  | |||
            "histogram" : { // 聚合类型为:histogram  | |||
                "field" : "price", // 根据price字段分桶  | |||
                "interval" : 50 // 分桶的间隔为50,意思就是 price 字段值按 50 间隔分组  | |||
            }  | |||
        }  | |||
    }  | |||
}  | |||
</syntaxhighlight>  | |||
返回结果:  | |||
<syntaxhighlight lang="JSON" highlight="">  | |||
{  | |||
    ...  | |||
    "aggregations": {  | |||
        "prices" : { // 聚合查询名字  | |||
            "buckets": [ // 分桶结果  | |||
                {  | |||
                    "key": 0.0, // 桶的标识,histogram 分桶,这里通常是分组的间隔值  | |||
                    "doc_count": 1 // 默认按 Value Count 指标聚合,统计桶内文档总数  | |||
                },  | |||
                {   | |||
                    "key": 50.0,  | |||
                    "doc_count": 1  | |||
                },  | |||
                {  | |||
                    "key": 100.0,  | |||
                    "doc_count": 0  | |||
                },  | |||
                {  | |||
                    "key": 150.0,  | |||
                    "doc_count": 2  | |||
                }  | |||
            ]  | |||
        }  | |||
    }  | |||
}  | |||
</syntaxhighlight>  | |||
== Date histogram 聚合 ==  | |||
类似 histogram 聚合,区别是 Date histogram 可以很好的处理时间类型字段,主要用于根据时间、日期分桶的场景。  | |||
示例:  | |||
<syntaxhighlight lang="JSON" highlight="">  | |||
POST /sales/_search?size=0  | |||
{  | |||
    "aggs" : {  | |||
        "sales_over_time" : { // 聚合查询名字,随便取一个  | |||
            "date_histogram" : { // 聚合类型为: date_histogram  | |||
                "field" : "date", // 根据date字段分组  | |||
                "calendar_interval" : "month", // 分组间隔:month代表每月、支持minute(每分钟)、hour(每小时)、day(每天)、week(每周)、year(每年)  | |||
                "format" : "yyyy-MM-dd" // 设置返回结果中桶key的时间格式  | |||
            }  | |||
        }  | |||
    }  | |||
}  | |||
</syntaxhighlight>  | |||
返回结果:  | |||
<syntaxhighlight lang="JSON" highlight="">  | |||
{  | |||
    ...  | |||
    "aggregations": {  | |||
        "sales_over_time": { // 聚合查询名字  | |||
            "buckets": [ // 桶聚合结果  | |||
                {  | |||
                    "key_as_string": "2015-01-01", // 每个桶key的字符串标识,格式由format指定  | |||
                    "key": 1420070400000, // key的具体字段值  | |||
                    "doc_count": 3 // 默认按Value Count指标聚合,统计桶内文档总数  | |||
                },  | |||
                {  | |||
                    "key_as_string": "2015-02-01",  | |||
                    "key": 1422748800000,  | |||
                    "doc_count": 2  | |||
                },  | |||
                {  | |||
                    "key_as_string": "2015-03-01",  | |||
                    "key": 1425168000000,  | |||
                    "doc_count": 2  | |||
                }  | |||
            ]  | |||
        }  | |||
    }  | |||
}  | |||
</syntaxhighlight>  | |||
== Range 聚合 ==  | |||
range聚合,按数值范围分桶。  | |||
示例:  | |||
<syntaxhighlight lang="JSON" highlight="">  | |||
GET /_search  | |||
{  | |||
    "aggs" : {  | |||
        "price_ranges" : { // 聚合查询名字,随便取一个  | |||
            "range" : { // 聚合类型为: range  | |||
                "field" : "price", // 根据price字段分桶  | |||
                "ranges" : [ // 范围配置  | |||
                    { "to" : 100.0 }, // 意思就是 price <= 100的文档归类到一个桶  | |||
                    { "from" : 100.0, "to" : 200.0 }, // price>100 and price<200的文档归类到一个桶  | |||
                    { "from" : 200.0 } // price>200的文档归类到一个桶  | |||
                ]  | |||
            }  | |||
        }  | |||
    }  | |||
}  | |||
</syntaxhighlight>  | |||
返回结果:  | |||
<syntaxhighlight lang="JSON" highlight="">  | |||
{  | |||
    ...  | |||
    "aggregations": {  | |||
        "price_ranges" : { // 聚合查询名字  | |||
            "buckets": [ // 桶聚合结果  | |||
                {  | |||
                    "key": "*-100.0", // key可以表达分桶的范围  | |||
                    "to": 100.0, // 结束值  | |||
                    "doc_count": 2 // 默认按Value Count指标聚合,统计桶内文档总数  | |||
                },  | |||
                {  | |||
                    "key": "100.0-200.0",  | |||
                    "from": 100.0, // 起始值  | |||
                    "to": 200.0, // 结束值  | |||
                    "doc_count": 2  | |||
                },  | |||
                {  | |||
                    "key": "200.0-*",  | |||
                    "from": 200.0,  | |||
                    "doc_count": 3  | |||
                }  | |||
            ]  | |||
        }  | |||
    }  | |||
}  | |||
</syntaxhighlight>  | |||
如上,可以发现 range 分桶,默认 key 的值不太友好,尤其开发的时候,不知道 key 长什么样子,处理起来比较麻烦,我们可以'''为每一个分桶指定一个有意义的名字'''。  | |||
示例:  | |||
<syntaxhighlight lang="JSON" highlight="">  | <syntaxhighlight lang="JSON" highlight="">  | ||
GET /_search  | |||
{  | |||
    "aggs" : {  | |||
        "price_ranges" : {  | |||
            "range" : {  | |||
                "field" : "price",  | |||
                "keyed" : true,  | |||
                "ranges" : [  | |||
                    // 通过key参数,配置每一个分桶的名字  | |||
                    { "key" : "cheap", "to" : 100 },  | |||
                    { "key" : "average", "from" : 100, "to" : 200 },  | |||
                    { "key" : "expensive", "from" : 200 }  | |||
                ]  | |||
            }  | |||
        }  | |||
    }  | |||
}  | |||
</syntaxhighlight>  | |||
== 综合示例 ==  | |||
实际应用中,经常需要配合query语句,先搜索目标文档,然后使用aggs聚合语句对搜索结果进行统计分析。  | |||
示例:  | |||
<syntaxhighlight lang="JSON" highlight="">  | |||
GET /cars/_search  | |||
{  | |||
    "size": 0, // size=0代表不需要返回query查询结果,仅仅返回aggs统计结果  | |||
    "query" : { // 设置查询语句,先赛选文档  | |||
        "match" : {  | |||
            "make" : "ford"  | |||
        }  | |||
    },  | |||
    "aggs" : { // 然后对query搜索的结果,进行统计  | |||
        "colors" : { // 聚合查询名字  | |||
            "terms" : { // 聚合类型为:terms 先分桶  | |||
              "field" : "color"  | |||
            },  | |||
            "aggs": { // 通过嵌套聚合查询,设置桶内指标聚合条件  | |||
              "avg_price": { // 聚合查询名字  | |||
                "avg": { // 聚合类型为: avg 指标聚合  | |||
                  "field": "price" // 根据price字段计算平均值  | |||
                }  | |||
              },  | |||
              "sum_price": { // 聚合查询名字  | |||
                "sum": { // 聚合类型为: sum 指标聚合  | |||
                  "field": "price" // 根据price字段求和  | |||
                }  | |||
              }  | |||
            }  | |||
        }  | |||
    }  | |||
}  | |||
</syntaxhighlight>  | </syntaxhighlight>  | ||
2021年5月21日 (五) 01:04的版本
关于
Elasticsearch 桶聚合,目的就是数据分组,先将数据按指定的条件分成多个组,然后对每一个组进行统计。
- 组的概念跟桶是等同的,在ES中统一使用桶(bucket)这个术语。
 
ES 桶聚合的作用跟 SQL 的 group by 的作用是一样的,区别是 ES 支持更加强大的数据分组能力,SQL 只能根据字段的唯一值进行分组,分组的数量跟字段的唯一值的数量相等。
- 例如: group by 店铺 id, 去掉重复的店铺 ID 后,有多少个店铺就有多少个分组。
 
ES常用的桶聚合如下:
- Terms 聚合:类似 SQL 的 group by,根据字段唯一值分组;
 - Histogram 聚合:根据数值间隔分组;
- 例如: 价格按100间隔分组,0、100、200、300等等
 
 - Date histogram 聚合:根据时间间隔分组;
- 例如:按月、按天、按小时分组
 
 - Range 聚合:按数值范围分组;
- 例如: 0-150一组,150-200一组,200-500一组。
 
 
- “桶聚合”一般不单独使用,都是配合“指标聚合”一起使用,对数据分组之后肯定要统计桶内数据,在 ES 中如果没有明确指定指标聚合,默认使用 Value Count 指标聚合,统计桶内文档总数。
 
Terms 聚合
terms 聚合的作用跟 SQL 中 group by 作用一样,都是根据字段唯一值对数据进行分组(分桶),字段值相等的文档都分到同一个桶内。
示例:
GET /order/_search?size=0
{
  "aggs": {
    "shop": { // 聚合查询的名字,随便取个名字
      "terms": { // 聚合类型为: terms
        "field": "shop_id" // 根据shop_id字段值,分桶
      }
    }
  }
}
等级SQL:
select shop_id, count(*) from order group by shop_id
返回结果:
{
    ...
    "aggregations" : {
        "shop" : { // 聚合查询名字
            "buckets" : [ // 桶聚合结果,下面返回各个桶的聚合结果
                {
                    "key" : "1", // key分桶的标识,在terms聚合中,代表的就是分桶的字段值
                    "doc_count" : 6 // 默认的指标聚合是统计桶内文档总数
                },
                {
                    "key" : "5",
                    "doc_count" : 3
                },
                {
                    "key" : "9",
                    "doc_count" : 2
                }
            ]
        }
    }
}
Histogram 聚合
histogram(直方图)聚合,主要根据数值间隔分组,使用 histogram 聚合分桶统计结果,通常用在绘制条形图报表。
示例:
POST /sales/_search?size=0
{
    "aggs" : {
        "prices" : { // 聚合查询名字,随便取一个
            "histogram" : { // 聚合类型为:histogram
                "field" : "price", // 根据price字段分桶
                "interval" : 50 // 分桶的间隔为50,意思就是 price 字段值按 50 间隔分组
            }
        }
    }
}
返回结果:
{
    ...
    "aggregations": {
        "prices" : { // 聚合查询名字
            "buckets": [ // 分桶结果
                {
                    "key": 0.0, // 桶的标识,histogram 分桶,这里通常是分组的间隔值
                    "doc_count": 1 // 默认按 Value Count 指标聚合,统计桶内文档总数
                },
                { 
                    "key": 50.0,
                    "doc_count": 1
                },
                {
                    "key": 100.0,
                    "doc_count": 0
                },
                {
                    "key": 150.0,
                    "doc_count": 2
                }
            ]
        }
    }
}
Date histogram 聚合
类似 histogram 聚合,区别是 Date histogram 可以很好的处理时间类型字段,主要用于根据时间、日期分桶的场景。
示例:
POST /sales/_search?size=0
{
    "aggs" : {
        "sales_over_time" : { // 聚合查询名字,随便取一个
            "date_histogram" : { // 聚合类型为: date_histogram
                "field" : "date", // 根据date字段分组
                "calendar_interval" : "month", // 分组间隔:month代表每月、支持minute(每分钟)、hour(每小时)、day(每天)、week(每周)、year(每年)
                "format" : "yyyy-MM-dd" // 设置返回结果中桶key的时间格式
            }
        }
    }
}
返回结果:
{
    ...
    "aggregations": {
        "sales_over_time": { // 聚合查询名字
            "buckets": [ // 桶聚合结果
                {
                    "key_as_string": "2015-01-01", // 每个桶key的字符串标识,格式由format指定
                    "key": 1420070400000, // key的具体字段值
                    "doc_count": 3 // 默认按Value Count指标聚合,统计桶内文档总数
                },
                {
                    "key_as_string": "2015-02-01",
                    "key": 1422748800000,
                    "doc_count": 2
                },
                {
                    "key_as_string": "2015-03-01",
                    "key": 1425168000000,
                    "doc_count": 2
                }
            ]
        }
    }
}
Range 聚合
range聚合,按数值范围分桶。
示例:
GET /_search
{
    "aggs" : {
        "price_ranges" : { // 聚合查询名字,随便取一个
            "range" : { // 聚合类型为: range
                "field" : "price", // 根据price字段分桶
                "ranges" : [ // 范围配置
                    { "to" : 100.0 }, // 意思就是 price <= 100的文档归类到一个桶
                    { "from" : 100.0, "to" : 200.0 }, // price>100 and price<200的文档归类到一个桶
                    { "from" : 200.0 } // price>200的文档归类到一个桶
                ]
            }
        }
    }
}
返回结果:
{
    ...
    "aggregations": {
        "price_ranges" : { // 聚合查询名字
            "buckets": [ // 桶聚合结果
                {
                    "key": "*-100.0", // key可以表达分桶的范围
                    "to": 100.0, // 结束值
                    "doc_count": 2 // 默认按Value Count指标聚合,统计桶内文档总数
                },
                {
                    "key": "100.0-200.0",
                    "from": 100.0, // 起始值
                    "to": 200.0, // 结束值
                    "doc_count": 2
                },
                {
                    "key": "200.0-*",
                    "from": 200.0,
                    "doc_count": 3
                }
            ]
        }
    }
}
如上,可以发现 range 分桶,默认 key 的值不太友好,尤其开发的时候,不知道 key 长什么样子,处理起来比较麻烦,我们可以为每一个分桶指定一个有意义的名字。
示例:
GET /_search
{
    "aggs" : {
        "price_ranges" : {
            "range" : {
                "field" : "price",
                "keyed" : true,
                "ranges" : [
                    // 通过key参数,配置每一个分桶的名字
                    { "key" : "cheap", "to" : 100 },
                    { "key" : "average", "from" : 100, "to" : 200 },
                    { "key" : "expensive", "from" : 200 }
                ]
            }
        }
    }
}
综合示例
实际应用中,经常需要配合query语句,先搜索目标文档,然后使用aggs聚合语句对搜索结果进行统计分析。
示例:
GET /cars/_search
{
    "size": 0, // size=0代表不需要返回query查询结果,仅仅返回aggs统计结果
    "query" : { // 设置查询语句,先赛选文档
        "match" : {
            "make" : "ford"
        }
    },
    "aggs" : { // 然后对query搜索的结果,进行统计
        "colors" : { // 聚合查询名字
            "terms" : { // 聚合类型为:terms 先分桶
              "field" : "color"
            },
            "aggs": { // 通过嵌套聚合查询,设置桶内指标聚合条件
              "avg_price": { // 聚合查询名字
                "avg": { // 聚合类型为: avg 指标聚合
                  "field": "price" // 根据price字段计算平均值
                }
              },
              "sum_price": { // 聚合查询名字
                "sum": { // 聚合类型为: sum 指标聚合
                  "field": "price" // 根据price字段求和
                }
              }
            }
        }
    }
}