好文推荐,可看这个:https://blog.youkuaiyun.com/weixin_40341116/article/details/81173016
一、简单查询+简单聚合(根据某字段分组)
1、模拟数据
PUT /shirts/_doc/1
{
"brand": "gucci",
"color": "red",
"model": "slim"
}
PUT /shirts/_doc/2
{
"brand": "gucci",
"color": "red",
"model": "slim"
}
PUT /shirts/_doc/3
{
"brand": "gucci",
"color": "red",
"model": "slim3"
}
PUT /shirts/_doc/4
{
"brand": "gucci",
"color": "green",
"model": "slim3"
}
2、
(1)执行聚合查询注释版,要复制粘贴的在更下面
GET /shirts/_search
{
"query": { #查询符合筛选条件的结果,
"bool": {
"filter": { #指定过滤器
"term": { "brand": "gucci" } #使用term这个过滤器,相当于sql的where
}
}
}, #这个query的作用等同于sql的select * from shirts where brand = 'gucci'
"aggs": { #聚合,注意后面是s,所以在这个aggs中是可以放多个聚合操作的。
#比如下面的colors和color_red就是两个聚合,colors和color_red是自定义的名字,作为对应聚合的名称
"colors": { #colors是一个聚合的名称,可以自定义,查询的相应结果也是以这个名称来响应,后面解释响应结果的时候会说
"terms": { "field": "color" } #terms指定聚合分组字段,简单理解就是对指定字段进行groupby。这里就是对color字段进行分组,后面可以看响应结果是什么
},
"color_red": { #聚合名称,自定义,但内容写法和colors有点区别,这个是对数据过滤之后再聚合。
"filter": { #指定了term过滤器,即where color = 'red'过滤出符合条件的数据,然后再继续下面的聚合
"term": { "color": "red" }
},
"aggs": { #定义当前的color_red这个聚合,注意看当前则个aggs的层级,是在color_red的下一级。
"models": { #自聚合名称
"terms": { "field": "model" } #terms指定聚合分组字段,和colors里的terms一样
}
}
}
},
"post_filter": { #后置过滤,就是再对一开始的query过滤出来的结果再进行一次过滤
"term": { "color": "red" } #想当于select * from result where color = 'red',其中result 指的是上面第一个query的结果
}
}
小小的说一句,上面的query还有另一个写法,效果是一样的,大家可以试一试
"query": {
"term": { "brand": "gucci" }
}
(2)可以复制粘贴版
GET /shirts/_search
{
"query": {
"bool": {
"filter": {
"term": { "brand": "gucci" }
}
}
},
"aggs": {
"colors": {
"terms": { "field": "color" }
},
"color_red": {
"filter": {
"term": { "color": "red" }
},
"aggs": {
"models": {
"terms": { "field": "model" }
}
}
}
},
"post_filter": {
"term": { "color": "red" }
}
}
3、查询结果如下
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": { #经过query和post_filter过滤之后的结果封装
"total": 3, #符合条件的结果数
"max_score": 0,
"hits": [ #结果列表
{
"_index": "shirts", #所属index
"_type": "_doc", #所属type
"_id": "2", #这是添加文档的时候指定的id
"_score": 0, #匹配评分,一般是分词之后才有用,指的是关键词匹配相关度,这里没用到,不管
"_source": { #这是真正的数据封装了,就是我们put进来的数据
"brand": "gucci",
"color": "red",
"model": "slim"
}
},
{
"_index": "shirts",
"_type": "_doc",
"_id": "1",
"_score": 0,
"_source": {
"brand": "gucci",
"color": "red",
"model": "slim"
}
},
{
"_index": "shirts",
"_type": "_doc",
"_id": "3",
"_score": 0,
"_source": {
"brand": "gucci",
"color": "red",
"model": "slim3"
}
}
]
},
#这是我们aggs聚合查询的结果(这缩写不就是查询时的那个aggs么),另外,这个aggregations的值的层级关系其实与查询时的聚合查询语句是对应的,可以自己对比看看。
"aggregations": {
"color_red": { #这是查询时发送的自定义的聚合名称
"doc_count": 3, #当前聚合所涉及的文档数量,还记得当前这个color_red聚合是指定了filter的吗,这doc_count的值指的就是符合filter的文档数。。然后在这三个文档中再进行聚合操作
"models": { #这个是查询时定义在color_red下的aggs,忘记里的可以去看看查询数据
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [ #聚合结果,名字不是自定义的,是es定的
{
"key": "slim", #按照model字段分组后,每组的model值
"doc_count": 2 #model字段值为slim的文档有2个
},
{
"key": "slim3", #按照model字段分组后,每组的model值
"doc_count": 1 #model字段值为slim3的文档有1个
}
]
}
},
"colors": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [ #聚合结果,名字不是自定义的,是es定的
{
"key": "red", #按照color字段分组后,每组的color值
"doc_count": 3 #color值为red的文档有2个
},
{
"key": "green",#按照color字段分组后,每组的color值
"doc_count": 1 #color值为red的文档有1个
}
]
}
}
}
上面例子参考官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/6.7/search-request-post-filter.html
二、聚合 https://blog.youkuaiyun.com/weixin_40341116/article/details/81173016
1、聚合aggs中terms是对指定字段分组,然后默认count计算每组的数量。 详细的 可以看:https://www.cnblogs.com/xing901022/p/4947436.html
2、还可以用avg,指的是对指定字段求平均值,例如:
GET my_index/_search
{
"aggs": {
"my_avg": {
"avg": {
"field": "age"
}
}
}
}
这就是对所有文档的age字段求平均值。
还有sum、min、max等等。可以参考:https://www.cnblogs.com/pilihaotian/p/5845754.html
3、terms分组之后对组内数据求sum、avg等操作
GET 127.0.0.1/mytest/doc/_search
{
"query": {
"match_all": {}
},
"size": 0,
"aggs": {
"my_name": {
"terms": {
"field": "color"
},
"aggs": { //嵌套两个指标avg、min在terms桶中
"my_avg_price": { //my_avg_price计算每个bucket的平均price
"avg": {
"field": "price"
}
},
"my_min_price": { //my_min_price计算每个bucket中的最小price
"min": {
"field": "price"
}
}
}
}
}
}
结果
"aggregations": {
"my_name": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [ //terms桶中的每个bucket都会计算avg和min两个指标
{
"key": "blue",
"doc_count": 1,
"my_avg_price": { //avg指标
"value": 1000
},
"my_min_price": { //min指标
"value": 100
}
},
{
"key": "red",
"doc_count": 2,
"my_avg_price": { //avg指标计算的值,因为符合color为red的文档有两笔,所以平均price为100+1000/2 = 550
"value": 550
},
"my_min_price": {
"value": 100
}
},
{
"key": "green",
"doc_count": 1,
"my_avg_price": {
"value": 500
},
"my_min_price": {
"value": 500
}
}
]
}
}