ES-ElasticSearch聚合命令

ES聚合命令

ES中的聚合查询类似于SQL的分组查询,主要用于统计分析场景。

查询流程为按需分组和桶内聚合

查询流程 流程功能 sql语句
按需分桶 对查询的数据根据需求进行初步筛选、并根据不同条件份桶,比如学生按专业分班的过程 group by
桶内聚合 对分桶的数据进行分析统计,比如统计一个班内学生的总数、平均成绩等 avg、sum、count

其中es的概念

相关概念 概念解释
桶bucket 满足特定条件的文档的集合
桶聚合 创建文档存储桶,把具有相同标准的数据分桶,并统计每个桶的文档数量
指标聚合 指标指的是对文档进行统计的计算方式,如sum、avg、count、max等

聚合查询基本命令

{
    
    
  "aggregations" : {
    
     # 指明以下为聚合查询语句,可以简写为aggs
    "<aggregation_name>" : {
    
     # 聚合计算的名字(随意命名)便于之后通过这个名字来获取想要的计算结果
        "<aggregation_type>" : {
    
     # 指定聚合类型,桶聚合和指标聚合
            <aggregation_body> # 聚合类型的参数,选择不同的聚合类型,有不同的参数
        }
        [,"aggregations" : {
    
     [<sub_aggregation>]+ } ]? # 嵌套聚合查询,支持多层嵌套
    }
    [,"<aggregation_name_2>" : {
    
     ... } ]* # 其他聚合查询的名称
  }
}

假设存在一个索引school,里边存储了所有的学生信息的文档,每个人都包含了字段class,希望通过字段class进行分组。

GET /school/_search
{
    
    
	"size" : 0, # 设置size=0的意思就是,仅返回聚合查询结果,不返回普通query查询结果。
    "aggs" : {
    
     # 聚合查询的简写
        "class_num" : {
    
     # 给聚合查询取个名字,叫class_num
            "terms" : {
    
     # 聚合类型为桶聚合的terms,类似SQL的group by的作用,相同字段值的文档分为一组。
              "field" : "class" # terms聚合类型的参数,这里需要设置分组的字段为class,根据color分组
            }
        }
    }
}

没有明确指定指标聚合函数默认使用Count聚合指标统计文档总数, 统计每一个class的学生人数,类似于sql语句:

select count(class) from school group by class

查询结果如下

{
    
    
...
   "hits": {
    
     # size=0,query查询结果不展示
      "hits": [] 
   },
   "aggregations": {
    
     # 聚合查询结果
      "class_num": {
    
     # class_num聚合查询的结果
         "buckets": [ # 桶聚合会返回buckets数组,代表分桶的统计情况,可以看到每个班的人数情况
            {
    
    
               "key": "Class_1", 
               "doc_count": 36 # 一班有36个人
            },
            {
    
    
               "key": " Class_2",
               "doc_count": 42 # 二班有42个人
            },
            {
    
    
               "key": "Class_3",
               "doc_count": 37 # 三班有37个人
            }
         ]
      }
   }
}

桶聚合

桶聚合,目的就是数据分组,先将数据按指定的条件分成多个组,然后对每一个组进行统计。每一个组就叫做桶(bucket)。桶聚合的作用跟SQL的group by的作用是一样的,但ES支持更加强大的数据分组能力。ES常用的桶聚合方法有:

聚合方法 方法解释
Terms聚合 类似SQL的group by,根据字段唯一值分组
Histogram聚合 根据数值间隔: 按100间隔分组产生0、100、200、300组
Date histogram聚合 根据时间间隔:按月、天、小时分组
Range聚合 按数值范围:比如分成 0-150、150-20、200-500三组

Terms聚合

terms聚合的作用跟SQL中group by作用一样,都是根据字段唯一值对数据进行分组(分桶),字段值相等的文档都分到同一个桶内

# 聚合命令
GET /school/_search
{
    
    
	"size" : 0, # 设置size=0的意思就是,仅返回聚合查询结果
	"aggs": {
    
     # aggs为聚合查询结果
		"class_bucket": {
    
     # 聚合查询的名字
			"terms": {
    
     # 聚合类型为:terms
				"field": "class" # 根据class字段值分桶
			}
		}
	}
}

相关sql语句

select class, count(*) from order group by class

查询结果如下

{
    
    
    ...
    "aggregations" : {
    
    
        "class_bucket" : {
    
     # 聚合查询名字
            "buckets" : [ # 桶聚合结果,下面返回各个桶的聚合结果
                {
    
    
                    "key" : "Class_1", # key分桶的标识,在terms聚合中,代表的就是分桶的字段值
                    "doc_count" : 36 # 默认的指标聚合是统计桶内文档总数
                },
                {
    
    
                    "key" : "Class_2",
                    "doc_count" : 42
                },
                {
    
    
                    "key" : "Class_3",
                    "doc_count" : 37
                }
            ]
        }
    }
}

Histogram聚合

histogram(直方图)聚合,主要根据数值间隔分组,使用histogram聚合分桶统计结果,通常用在绘制条形图报表

# 聚合命令
GET /school/_search
{
    
    
	"size" : 0, # 设置size=0的意思就是,仅返回聚合查询结果
	"aggs": {
    
     # aggs为聚合查询结果
		"histogram_grade": {
    
     # 聚合查询的名字
			"histogram": {
    
     # 聚合类型为:histogram
				"field": "grade" # 根据price字段分桶
				"interval": 50 # 分桶的间隔为50,意思就是grade字段值按50间隔分组
			}
		}
	}
}
# 查询结果如下
{
    
    
    ...
    "aggregations": {
    
    
        "histogram_grade" : {
    
     # 聚合查询名字
            "buckets": [ # 分桶结果
                {
    
    
                    "key": 0.0, # 桶的标识,histogram分桶,这里通常是分组的间隔值,从0开始
                    "doc_count": 0 # 默认按Value Count指标聚合,统计桶内文档总数
                },
                {
    
     
                    "key": 50.0,
                    "doc_count": 115
                }
            ]
        }
    }
}

Date histogram聚合

类似histogram聚合,但Date histogram可以很好的处理时间类型字段,主要用于根据时间、日期分桶的场景

# 聚合命令
GET /school/_search
{
    
    
	"size" : 0, # 设置size=0的意思就是,仅返回聚合查询结果
	"aggs": {
    
     # aggs为聚合查询结果
		"data_of_birth": {
    
     # 聚合查询的名字
			"date_histogram": {
    
     # 聚合类型为:date_histogram
				"field": "date" # 根据date字段分桶
				"calendar_interval" : "year", # 分组间隔:month代表每月、支持minute(每分钟)、hour(每小时)、day(每天)、week(每周)、year(每年)
				"format" : "yyyy-MM-dd" # 设置返回结果中桶key的时间格式
			}
		}
	}
}
# 查询结果如下
{
    
    
    ...
    "aggregations": {
    
    
        "data_of_birth": {
    
     # 聚合查询名字
            "buckets": [ # 桶聚合结果
                {
    
    
                    "key_as_string": "2005-01-01", # 每个桶key的字符串标识,格式由format指定
                    "key": 1104537600000, # key的具体字段值,13位时间戳
                    "doc_count": 3 # 默认按Value Count指标聚合,统计桶内文档总数
                },
                {
    
    
                    "key_as_string": "2006-01-01",
                    "key": 1136073600000,
                    "doc_count": 2
                },
                {
    
    
                    "key_as_string": "2007-01-01",
                    "key": 1167609600000,
                    "doc_count": 2
                },
                ...
            ]
        }
    }
}

Range聚合

自己设计范围,按数值范围分桶

# 聚合命令
GET /school/_search
{
    
    
	"size" : 0, # 设置size=0的意思就是,仅返回聚合查询结果
	"aggs": {
    
     # aggs为聚合查询结果
		"range_grade": {
    
     # 聚合查询的名字
			"range": {
    
     # 聚合类型为:range
				"field": "grade" # 根据price字段分桶
				"ranges": [ # 配置范围
					{
    
    "key" : "failing", "to": 60.0}, # grade <= 60的文档归类到failing桶
					{
    
    "key" : "good", "from": 60.0, "to": 80.0}, # 60<grade<80的文档归类到good桶
					{
    
    "key" : "excellent", "from": 80.0} # grade>80的文档归类到excellent桶
				]
			}
		}
	}
}
# 查询结果如下
{
    
    
    ...
    "aggregations": {
    
    
        "range_grade" : {
    
     # 聚合查询名字
            "buckets": [ # 桶聚合结果
                {
    
    
                    "key": "failing", # 桶名称
                    "to": 60.0, # 结束值
                    "doc_count": 42 # 默认按Value Count指标聚合,统计桶内文档总数
                },
                {
    
    
                    "key": "good",
                    "from": 60.0, # 起始值
                    "to": 80.0, # 结束值
                    "doc_count": 50
                },
                {
    
    
                    "key": "excellent",
                    "from": 80.0,
                    "doc_count": 23
                }
            ]
        }
    }
}

指标聚合

指标聚合,类似sql的统计函数,指标聚合可以单独使用,也可以跟桶聚合一起用。常用的统计函数有:

指标名称 值聚合Value Count 基数聚合Cardinality Avg Sum Max Min
指标功能 统计总数 统计不重复的数据总数 求平均值 求和 求最大值 求最小值

Value Count

值聚合,主要用于统计文档总数,类似SQL的count函数

# 聚合命令
GET /school/_search
{
    
    
	"size" : 0, # 设置size=0的意思就是,仅返回聚合查询结果
	"aggs": {
    
     # aggs为聚合查询结果
		"age_count": {
    
     # 聚合查询的名字
			"value_count": {
    
     # 聚合类型为:value_count
				"field": "age" # 计算age这个字段值的总数
			}
		}
	}
}

相关sql语句

select count(age) from school

查询结果如下

{
    
    
    ...
	"aggregations": {
    
    
        "age_count": {
    
     # 聚合查询的名字
            "value": 115 # 统计结果,假设学生的年龄均在12-18之间,没有去重所以结果等于学生总数
        }
    }
}

Cardinality

基数聚合,也是用于统计文档的总数,跟Value Count的区别是,基数聚合会去重,不会统计重复的值,类似SQL的count(DISTINCT 字段)用法

# 聚合命令
GET /school/_search
{
    
    
	"size" : 0, # 设置size=0的意思就是,仅返回聚合查询结果
	"aggs": {
    
     # aggs为聚合查询结果
		"age_count": {
    
     # 聚合查询的名字
			"cardinality": {
    
     # 聚合类型为:cardinality
				"field": "age" # 计算age这个字段值的总数
			}
		}
	}
}

相关sql语句

select count(DISTINCT age) from school

查询结果如下

{
    
    
    ...
	"aggregations": {
    
    
        "types_count": {
    
     # 聚合查询的名字
            "value": 7 # 统计结果,假设学生的年龄均在12-18岁之间,去重所以结果等于不同年龄数值
        }
    }
}

Avg

计算字段值的平均值

# 聚合命令
GET /school/_search
{
    
    
	"size" : 0, # 设置size=0的意思就是,仅返回聚合查询结果
	"aggs": {
    
     # aggs为聚合查询结果
		"avg_grade": {
    
     # 聚合查询的名字,学生成绩平均
			"avg": {
    
     # 聚合类型为:avg
				"field": "grade" # 计算grade这个字段值的平均值
			}
		}
	}
}
# 查询结果如下
{
    
    
    ...
	"aggregations": {
    
    
        "avg_grade": {
    
     # 聚合查询的名字
            "value": 80.0 # 统计结果,学生成绩的平均值
        }
    }
}

Sum

计算字段值的总和

# 聚合命令
GET /school/_search
{
    
    
	"size" : 0, # 设置size=0的意思就是,仅返回聚合查询结果
	"aggs": {
    
     # aggs为聚合查询结果
		"sum_grade": {
    
     # 聚合查询的名字,学生成绩总和
			"sum": {
    
     # 聚合类型为:sum
				"field": "grade" # 计算grade这个字段值的总和
			}
		}
	}
}
# 查询结果如下
{
    
    
    ...
	"aggregations": {
    
    
        "sum_grade": {
    
     # 聚合查询的名字
            "value": 9200 # 统计结果,(avg_grade = 80) * (age_count = 115) = (sum_grade = 9200)
        }
    }
}

Max

获得字段的最大值

# 聚合命令
GET /school/_search
{
    
    
	"size" : 0, # 设置size=0的意思就是,仅返回聚合查询结果
	"aggs": {
    
     # aggs为聚合查询结果
		"max_grade": {
    
     # 聚合查询的名字,学生的最好成绩
			"max": {
    
     # 聚合类型为:max
				"field": "grade" # 计算grade这个字段值的最大值
			}
		}
	}
}
# 查询结果如下
{
    
    
    ...
	"aggregations": {
    
    
        "max_grade": {
    
     # 聚合查询的名字
            "value": 100 # 统计结果,学生最高分为100
        }
    }
}

Min

获得字段的最小值

# 聚合命令
GET /school/_search
{
    
    
	"size" : 0, # 设置size=0的意思就是,仅返回聚合查询结果
	"aggs": {
    
     # aggs为聚合查询结果
		"min_grade": {
    
     # 聚合查询的名字,学生最低成绩
			"min": {
    
     # 聚合类型为:min
				"field": "grade" # 计算grade这个字段值的最小值
			}
		}
	}
}
# 查询结果如下
{
    
    
    ...
	"aggregations": {
    
    
        "min_grade": {
    
     # 聚合查询的名字
            "value": 60 # 统计结果,学生最低分为60
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42078712/article/details/129879899
今日推荐