GET testindex/_search
{
"size": 0,
"aggs": { // 关键词,与query 同级
"agg_name": { // 自定义的聚合名称
"agg_type": { // 聚合分析的定义,包含type 和 body 定义
"agg_body"
},
[,"aggs": {"sub_agg"}] // 子聚合
},
"agg_name2": {....} // 可以包含多个聚合
}
}
Bucket,意味 ’桶‘,即按照一定的规则将文档分配到不同的桶中,达到分类的目的。
按照Bucket 的分桶策略,常见的Bucket 聚合分析如下:
Terms:直接按照term来分桶。如果是text 类型(需要开启fielddata),则按照分词后的结果分桶。
Range:通过制定数值的范围内设定分桶规则
// *-10000,10000-20000,20000-* 三个区间的文档数聚合
GET testinde/_search
{
"aggs": {
"salary_range": {
"range": {
"field": "salary",
"ranges": [
{
"key": "<10000", // 自定义key 值的名字
"to": 10000
},
{
"from": 10000,
"to": 20000,
},
{
"from": 20000
}
]
}
}
}
}
Date Range:通过制定日期的范围来设定分桶规则
GET testindex/_search
{
"aggs": {
"date_range": {
"range": {
"field": "birth",
"format": "yyyy-MM-dd", // 指定返回结果的日期格式
"ranges": [
{
"from": "2019-09-01", // 指定日期范围,可以使用date match
"to": "2019-09-30"
}
]
}
}
}
}
GET testindex/_search
{
"aggs": {
"salary_hist": {
"histogram": { // 关键词
"field": "salary",
"interval": 5000, // 指定间隔大小
"extended_bounds": { // 指定数据范围
"min": 0,
"max": 50000
}
}
}
}
}
GET testindex/_search
{
"aggs": {
"by_year": {
"date_histogram": { // 关键词
"field": "birth",
"interval": "year", // 指定间隔大小
"format": "yyyy"
}
}
}
}
主要分如下2类:
1、cardinality
集合的势,或者基数,是指不同数值的个数。可以类比成 SQL 中的 distinct count意思。分组求和,比如某列的数值有多个不同的值。
2、stats
返回一系列数值类型的统计值,包含了min、max、avg、sum和count。一次做了多种分析。
3、extended_stats
顾名思义,是对stats的扩展,包含了更多的统计数据,如方差、标准差等。
4、percentiles与percentile_ranks
百分位数统计。如下:
// 比如:第一行的意思是18岁以下的人数占1.0%
{
"took": 55,
......
"aggregations": {
"per_age": {
"1.0": 18,
"5.0": 25,
"25.0": 29,
"50.0": 31,
"75.0": 40,
"95.0": 60,
"99.0": 80
}
}
}
// 指定展示的百分位数(只展示95%,99%,99.9%的数据)
GET testindex/_search
{
"aggs": {
"per_salary": {
"percentiles": {
"field": "salary",
"percents": [
95,
99,
99.9
]
}
}
}
}
5、top_hits
一般用于分桶聚合后,获取该桶内最匹配的顶部文档列表,即详情数据。如下:
GET testindex/_search
{
"aggs": {
"group_jobs": {
"terms": { // 分桶聚合
"field": "job.keyword"
},
"aggs": {
"top_employee": {
"top_hits": { // 关键词
"size": 10,
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
}
}
}
}
}
Bucket 聚合分析允许通过添加子分析来进一步分析,该子分析可以是 Bucket 也可以是 Metric。
pipeline的分析结果会输出到原结果中,根据输出位置的不同,可以分为2类。
1、parent 结果内嵌到现有的聚合分析结果中:
2、Sibling 结果与现有聚合分析结果同级
es聚合分析默认作用范围是 query 的结果集,可以通过 filter、post_filter、global 改变其作用范围。
它是为某个聚合分析设定过滤条件的,从而在不更改整体query 语句的情况下修改作用范围。
作用于文档过滤,但在聚合分析后生效,过滤输出的结果。
无视query的过滤条件,基于全部文档进行分析。比如你在query里面进行了文档过滤,但是global还是会基于全部文档去分析。
可以使用自带的关键数据进行排序,比如:
GET testindex/_search
{
"aggs": {
"group_jobs": {
"terms": { // 分桶聚合
"field": "job.keyword",
"order": { // 排序
"_count": "asc"
}
}
}
}
}
max、min这种是精确地,但是 terms 是不一定精确地。可以通过参数来优化它。
terms 聚合返回结果中有如下2个统计值:
注:shard_size大小的设定方法
设定show_term_doc_count_error=true可以查看每个bucket误算的最大值。当其返回结果的doc_count_error_upper_bound=0,则说明计算是准确的,不存在误差。
GET testindex/_search
{
"aggs": {
"jobs": {
"terms": {
"field": "job.keyword",
"show_term_doc_count_error": true
}
}
}
}
shard_size默认大小如下:shard_size=size * 1.5 + 10
通过调整shard_size 的大小降低doc_count_error_upper_bound来提升准确度(随之而来的影响是增大了整体的计算量,从而降低了响应时间)
GET testindex/_search
{
"aggs": {
"jobs": {
"terms": {
"field": "job.keyword",
"shard_size": 10, // 关键词
"show_term_doc_count_error": true
}
}
}
}
第一步,设置mapping(指定分词器和开启fielddata,因为你想要分词,所以type毫无疑问是text)
PUT test
{
"mappings": {
"doc": {
"properties": {
"hello": {
"type": "text",
"analyzer": "ik_max_word",
"fielddata": true
}
}
}
}
}
第二步,插入测试数据
PUT test/doc/1
{
"hello": "北京加油"
}
第三步,聚合查询
GET test/_search
{
"query": {
"match_all": {}
},
"aggs": {
"NAME": {
"terms": {
"field": "hello",
"size": 10
}
}
}
}
结果如下:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "test123",
"_type": "doc",
"_id": "1",
"_score": 1,
"_source": {
"hello": "北京加油"
}
}
]
},
"aggregations": {
"NAME": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "北京",
"doc_count": 1
},
{
"key": "加油",
"doc_count": 1
}
]
}
}
}