Skip to content

聚合查询


数据聚合即数据的统计分析。常见的聚合方式如下

  • 桶聚合:对数据进行分组,相当于sql的group by
  • 指标聚合:对数据集使用max() 、min()、avg()、sum()之类的聚合函数,统计最大值、最小值、平均值、总量等指标

主要概念

  • 桶(bucket):满足特定条件的文档集合,实质是基于条件来划分文档
  • 指标(metric):数据集的一些特征值,比如最大值、最小值、平均值

支持嵌套,桶聚合可以嵌套桶聚合、指标聚合,指标聚合也可以嵌套桶聚合、指标聚合。

对于嵌套的聚合,es只需遍历一次数据,不用多次循环遍历数据,速度快、性能高,但聚合、排序都很耗内存。

聚合可以对index中的所有文档使用,也可以对查询结果使用。

只能对keyword字段使用聚合,不能对text字段使用聚合,如果对text使用聚合,会报错

桶聚合

#对全样数据进行聚合,eg. 统计每个球队的球员(人数)
GET /nba/_search
{
    "aggs": {
        "team_buckets": {  #自定义的聚合名称
            "terms": {  #按关键字划分。不能换成term、match
                "field": "team_name",  #指定要聚合的字段。按队名划分桶,一个队一个桶,桶内是该队所有球员的文档,字段的值即桶名
              # "include": ["湖人队","公牛队","勇士队"],  #指定参与聚合的值,只聚合这些值
			  # "exclude": ["湖人队"],  #指定不参与聚合的值,除了这些值其它都参与聚合
                "size": 10,  #返回的桶数,默认返回所有的桶
		      #	"order": {  #桶的排序方式
		      #     "_count": "desc"  #按桶中的文档数降序排列,默认也是按桶中的文档数降序排列
		      #  }
            }
        }
    },
    "size": 0  #返回的文档数,默认返回每个桶中的所有文档,设置为0即不返回文档,可提高查询速度。如果不需要获取具体文档,可设置为0
}

#include、exclude可以使用通配符,点号表示任意一个字符,*表示任意多个字符

#按范围划分桶之自定义区间,eg.统计指定年龄区间上的用户数量
GET /user/_search
{
    "aggs": {
        "age_range": {  #自定义的聚合名称
            "range": {  #按范围划分
                "field": "age",  #指定字段
                "ranges": [  #划分区间
                    {
                        "to": 12,  # [from,to),只要有一个即可
                        "key": "12岁以下"  #区间别名,类似于sql查询结果集的字段别名,非必需
                    },
                    {
                        "from": 12,
                        "to": 18,
                        "key": "12~18岁"
                    },
                    {
                        "from": 18,
                        "key": "18岁以上"
                    }
                ]
            }
        }
    },
    "size": 0
}

#按时间日期划分桶

*   year(1y)年
*   quarter(1q)季度
*   month(1M)月份
*   week(1w)星期
*   day(1d)天
*   hour(1h)小时
*   minute(1m)分钟
*   second(1s)秒

"query": {
    "bool": {
        "must": [{
            "range": {
                "@timestamp": {
                    "gte": 1533556800000,
                    "lte": 1533806520000
                }
            }
        }]
    }
},
// 不显示具体的内容
"size": 0,
// 聚合
"aggs": {
    // 自己取的聚合名字
    "group_by_grabTime": {
        // es提供的时间处理函数
        "date_histogram": {
            // 需要聚合分组的字段名称, 类型需要为date, 格式没有要求
            "field": "@timestamp",
            // 按什么时间段聚合, 这里是5分钟, 可用的interval在上面给出
            "interval": "5m",
            // 设置时区, 这样就相当于东八区的时间
            "time_zone":"+08:00",
            // 返回值格式化,HH大写,不然不能区分上午、下午
            "format": "yyyy-MM-dd HH",   
            // 为空的话则填充0
            "min_doc_count": 0,
            // 需要填充0的范围
            "extended_bounds": {
                "min": 1533556800000,
                "max": 1533806520000
            }
        },
        // 聚合
        "aggs": {
            // 自己取的名称
            "group_by_status": {
                // es提供
                "terms": {
                    // 聚合字段名
                    "field": "LowStatusOfPrice"
                }
            }
        }
    }
}
#对全样数据进行聚合,eg. 统计每个球队的球员(人数)
GET /nba/_search
{
    "aggs": {
        "team_buckets": {  #自定义的聚合名称
            "terms": {  #按关键字划分。不能换成term、match
                "field": "team_name",  #指定要聚合的字段。按队名划分桶,一个队一个桶,桶内是该队所有球员的文档,字段的值即桶名
              # "include": ["湖人队","公牛队","勇士队"],  #指定参与聚合的值,只聚合这些值
			  # "exclude": ["湖人队"],  #指定不参与聚合的值,除了这些值其它都参与聚合
                "size": 10,  #返回的桶数,默认返回所有的桶
		      #	"order": {  #桶的排序方式
		      #     "_count": "desc"  #按桶中的文档数降序排列,默认也是按桶中的文档数降序排列
		      #  }
            }
        }
    },
    "size": 0  #返回的文档数,默认返回每个桶中的所有文档,设置为0即不返回文档,可提高查询速度。如果不需要获取具体文档,可设置为0
}

#include、exclude可以使用通配符,点号表示任意一个字符,*表示任意多个字符

#按范围划分桶之自定义区间,eg.统计指定年龄区间上的用户数量
GET /user/_search
{
    "aggs": {
        "age_range": {  #自定义的聚合名称
            "range": {  #按范围划分
                "field": "age",  #指定字段
                "ranges": [  #划分区间
                    {
                        "to": 12,  # [from,to),只要有一个即可
                        "key": "12岁以下"  #区间别名,类似于sql查询结果集的字段别名,非必需
                    },
                    {
                        "from": 12,
                        "to": 18,
                        "key": "12~18岁"
                    },
                    {
                        "from": 18,
                        "key": "18岁以上"
                    }
                ]
            }
        }
    },
    "size": 0
}

#按时间日期划分桶

*   year(1y)年
*   quarter(1q)季度
*   month(1M)月份
*   week(1w)星期
*   day(1d)天
*   hour(1h)小时
*   minute(1m)分钟
*   second(1s)秒

"query": {
    "bool": {
        "must": [{
            "range": {
                "@timestamp": {
                    "gte": 1533556800000,
                    "lte": 1533806520000
                }
            }
        }]
    }
},
// 不显示具体的内容
"size": 0,
// 聚合
"aggs": {
    // 自己取的聚合名字
    "group_by_grabTime": {
        // es提供的时间处理函数
        "date_histogram": {
            // 需要聚合分组的字段名称, 类型需要为date, 格式没有要求
            "field": "@timestamp",
            // 按什么时间段聚合, 这里是5分钟, 可用的interval在上面给出
            "interval": "5m",
            // 设置时区, 这样就相当于东八区的时间
            "time_zone":"+08:00",
            // 返回值格式化,HH大写,不然不能区分上午、下午
            "format": "yyyy-MM-dd HH",   
            // 为空的话则填充0
            "min_doc_count": 0,
            // 需要填充0的范围
            "extended_bounds": {
                "min": 1533556800000,
                "max": 1533806520000
            }
        },
        // 聚合
        "aggs": {
            // 自己取的名称
            "group_by_status": {
                // es提供
                "terms": {
                    // 聚合字段名
                    "field": "LowStatusOfPrice"
                }
            }
        }
    }
}

指标聚合

常用的聚合函数

  • value_count 该字段有值(不为空)的文档数
  • max 最大值
  • min 最小值
  • avg 平均值
  • sum 总量
  • stats 同时统计以上5个指标
  • extended_stats 统计更多的信息,比如平⽅和、⽅差、标准差
  • cardinality 去重计数
#对全样数据进行聚合,eg. 统计nba球员的平均年龄
GET /nba/_search
{
    "aggs": {
        "avg_age": {  #自定义的聚合名称
            "avg": {  #要使用的聚合函数
                "field": "age"  #要统计的字段
            }
        }
    },
    "size": 0
}


#对查询结果进行聚合,eg. 统计⽕箭队球员的平均年龄
GET /nba/_search
{
    "query": {
        "term": {
            "team_name": "火箭队"
        }
    },
    "aggs": {
        "avgAge": {
            "avg": {
                "field": "age"
            }
        }
    },
    "size": 0
}


#去重计数,eg. 统计某个活动的中奖人数
POST /raffle/_search
{
    "query": {
        "term": {
            "activity_id": 123
        }
    },
    "aggs": {
        "coun_user": {
            "cardinality": {
                "field": "user_id"
            }
        }
    },
    "size": 0
}
#对全样数据进行聚合,eg. 统计nba球员的平均年龄
GET /nba/_search
{
    "aggs": {
        "avg_age": {  #自定义的聚合名称
            "avg": {  #要使用的聚合函数
                "field": "age"  #要统计的字段
            }
        }
    },
    "size": 0
}


#对查询结果进行聚合,eg. 统计⽕箭队球员的平均年龄
GET /nba/_search
{
    "query": {
        "term": {
            "team_name": "火箭队"
        }
    },
    "aggs": {
        "avgAge": {
            "avg": {
                "field": "age"
            }
        }
    },
    "size": 0
}


#去重计数,eg. 统计某个活动的中奖人数
POST /raffle/_search
{
    "query": {
        "term": {
            "activity_id": 123
        }
    },
    "aggs": {
        "coun_user": {
            "cardinality": {
                "field": "user_id"
            }
        }
    },
    "size": 0
}

嵌套聚合

#桶聚合嵌套指标聚合。先桶聚合按球队划分球员,再指标聚合得到每只球队球员的平均年龄,再按平均年龄对桶进行排序
GET /nba/_search
{
    "aggs": {
        "team_avg_age": {
            "terms": {
                "field": "team_name",
                "order": {
                    "avg_age": "asc"  #avg_age是年龄聚合的名称
                }
            },
            "aggs": {
                "avg_age": {
                    "avg": {
                        "field": "age"
                    }
                }
            }
        }
    },
    "size": 0
}

#桶嵌套桶。先按省份划分用户,再在每个桶中按城市划分
GET /user/_search
{
    "aggs": {
        "count_province": {
            "terms": {
                "field": "province"
            },
            "aggs": {
                "count_province_city": {
                    "terms": {
                        "field": "city"
                    }
                }
            }
        }
    },
    "size": 0
}
#桶聚合嵌套指标聚合。先桶聚合按球队划分球员,再指标聚合得到每只球队球员的平均年龄,再按平均年龄对桶进行排序
GET /nba/_search
{
    "aggs": {
        "team_avg_age": {
            "terms": {
                "field": "team_name",
                "order": {
                    "avg_age": "asc"  #avg_age是年龄聚合的名称
                }
            },
            "aggs": {
                "avg_age": {
                    "avg": {
                        "field": "age"
                    }
                }
            }
        }
    },
    "size": 0
}

#桶嵌套桶。先按省份划分用户,再在每个桶中按城市划分
GET /user/_search
{
    "aggs": {
        "count_province": {
            "terms": {
                "field": "province"
            },
            "aggs": {
                "count_province_city": {
                    "terms": {
                        "field": "city"
                    }
                }
            }
        }
    },
    "size": 0
}

百分比

#查看学生成绩的分布情况
POST /student/_search
{
    "aggs": {
        "percent_score": {
            "percentiles": {
                "field": "score",
                "percents": [25, 50, 75]  #指定百分比的分数,缺省时默认为 [1.0, 5.0, 25.0, 50.0, 75.0, 95.0, 99.0]
            }
        }
    },
    "size": 0
}
#查看学生成绩的分布情况
POST /student/_search
{
    "aggs": {
        "percent_score": {
            "percentiles": {
                "field": "score",
                "percents": [25, 50, 75]  #指定百分比的分数,缺省时默认为 [1.0, 5.0, 25.0, 50.0, 75.0, 95.0, 99.0]
            }
        }
    },
    "size": 0
}

图表

#eg. 统计学生成绩的分布情况。也属于桶聚合
GET /student/_search
{
   "aggs":{
      "socre_info":{
         "histogram":{
            "field": "score",
            "interval": 20  #指定间距。[0,20),[20,40)...一个区间一个桶,区间上有文档时才划分为桶
         }
      }
   },
   "size" : 0
}

#按成绩划分区间(桶),统计每个区间上的文档,再计算每个桶内的平均分。桶聚合+指标聚合
GET /student/_search
{
    "aggs": {
        "socre_info": {
            "histogram": {
                "field": "score",
                "interval": 20
            },
            "aggs": {
                "avg_score": {
                    "avg": {
                        "field": "score"
                    }
                }
            }
        }
    },
    "size": 0
}
#eg. 统计学生成绩的分布情况。也属于桶聚合
GET /student/_search
{
   "aggs":{
      "socre_info":{
         "histogram":{
            "field": "score",
            "interval": 20  #指定间距。[0,20),[20,40)...一个区间一个桶,区间上有文档时才划分为桶
         }
      }
   },
   "size" : 0
}

#按成绩划分区间(桶),统计每个区间上的文档,再计算每个桶内的平均分。桶聚合+指标聚合
GET /student/_search
{
    "aggs": {
        "socre_info": {
            "histogram": {
                "field": "score",
                "interval": 20
            },
            "aggs": {
                "avg_score": {
                    "avg": {
                        "field": "score"
                    }
                }
            }
        }
    },
    "size": 0
}

备案号:冀ICP备20015584号-2