elasticsearch6 聚合查询

好文推荐,可看这个:https://blog.csdn.net/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.csdn.net/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
                }
            }
        ]
    }
}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值