0
点赞
收藏
分享

微信扫一扫

ES聚合中的Filter Bucket(过滤桶)详解


过滤桶 (Filter Bucket) 对聚合结果进行过滤

       平常的过滤我们可以查询然后包括一个过滤器 (filter) 返回一组文档的子集但是如果我们只想对聚合结果过滤怎么办? 假设我们正在为汽车经销商创建一个搜索页面, 我们希望显示出​​ford​​​上个月售出的汽车的平均售价
这里我们无法简单的做范围限定,因为有两个不同的条件。搜索结果必须是 ​​​ford​​​ ,但是聚合结果必须是 ​​ford​​​ 且 销售时间是在一个月前(​​sold > now - 1M​​) 。

       为了解决这个问题,我们可以用一种特殊的桶,叫做 ​​filter​​ (过滤桶) 。 我们可以指定一个过滤桶,当文档满足过滤桶的条件时,我们将其加入到桶内。

       查询语句如下: avg 度量会对 ford 和上个月售出的文档计算平均售价

GET /cars/transactions/_search
{
"size" : 0,
"query":{
"match": {
"make": "ford"
}
},
"aggs":{
"recent_sales": {
"filter": {
"range": {
"sold": {
"from": "now-1M"
}
}
},
"aggs": {
"average_price":{
"avg": {
"field": "price"
}
}
}
}
}
}

具体分类如下:

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站​​点击跳转浏览。​​

单个过滤器(filter)聚合

       定义当前文档集上下文中匹配指定过滤器(filter)的所有文档的单个桶。 这通常用于将当前的聚合上下文缩小到一组特定的文档。

示例:

POST /sales/_search?size=0
{
"aggs" : {
"t_shirts" : {
"filter" : { "term": { "type": "t-shirt" } },
"aggs" : {
"avg_price" : { "avg" : { "field" : "price" } }
}
}
}
}

上面的例子计算了所有 t-shirt 类型产品的平均价格(price)。

响应:

{
...
"aggregations" : {
"t_shirts" : {
"doc_count" : 3,
"avg_price" : { "value" : 128.33333333333334 }
}
}
}

多个过滤器(filters)聚合 多桶聚合

定义一个多桶聚合,其中每个桶都与一个过滤器相关联。每个桶都会收集与其关联的过滤器匹配的所有文档。

示例:例如想知道包含错误和包含警告的各自的数量

PUT /logs/_bulk?refresh
{ "index" : { "_id" : 1 } }
{ "body" : "warning: page could not be rendered" }
{ "index" : { "_id" : 2 } }
{ "body" : "authentication error" }
{ "index" : { "_id" : 3 } }
{ "body" : "warning: connection timed out" }

GET logs/_search
{
"size": 0,
"aggs" : {
"messages" : {
"filters" : {
"filters" : {
"errors" : { "match" : { "body" : "error" }},
"warnings" : { "match" : { "body" : "warning" }}
}
}
}
}
}

响应:

{
"took": 9,
"timed_out": false,
"_shards": ...,
"hits": ...,
"aggregations": {
"messages": {
"buckets": {
"errors": {
"doc_count": 1
},
"warnings": {
"doc_count": 2
}
}
}
}
}

匿名过滤器

filters 字段也可以指定为一个筛选器数组,比如下面这个请求:

GET logs/_search
{
"size": 0,
"aggs" : {
"messages" : {
"filters" : {
"filters" : [
{ "match" : { "body" : "error" }},
{ "match" : { "body" : "warning" }}
]
}
}
}
}

过滤后的桶按照请求中给定的顺序返回。这个例子的响应是:

{
"took": 4,
"timed_out": false,
"_shards": ...,
"hits": ...,
"aggregations": {
"messages": {
"buckets": [
{
"doc_count": 1
},
{
"doc_count": 2
}
]
}
}
}

其他桶(​​other_bucket​​)

过滤桶可以设置 ​​other_bucket​​ 参数,以便向响应中添加一个桶,该桶将包含不匹配任何给定的过滤器的所有文档。 该参数的值可以设置为:

  • false​​
    不会计算 ​​other​​ 桶
  • true​​
    计算并返回 ​​other​​ 桶,当使用命名过滤器时返回一个命名(默认名称为 ​​_other_​​)的桶,否则(使用匿名过滤器时)就是返回的桶中的最后一个

参数 ​​other_bucket_key​​​ 可用于设置 ​​other​​​ 桶的键,以取代默认的​​_other_​​​。 设置此参数将隐式地将 ​​other_bucket​​​ 参数设置为​​true​​。

下面的代码片段显示了一个响应,其中 ​​other​​​ 桶在请求中被命名为 ​​other_messages​​。

//向之前的索引中加一条数据
PUT logs/_doc/4?refresh
{
"body": "info: user Bob logged out"
}
// 再次查询
GET logs/_search
{
"size": 0,
"aggs" : {
"messages" : {
"filters" : {
"other_bucket_key": "other_messages",
"filters" : {
"errors" : { "match" : { "body" : "error" }},
"warnings" : { "match" : { "body" : "warning" }}
}
}
}
}
}

响应应该是这样的:

{
"took": 3,
"timed_out": false,
"_shards": ...,
"hits": ...,
"aggregations": {
"messages": {
"buckets": {
"errors": {
"doc_count": 1
},
"warnings": {
"doc_count": 2
},
"other_messages": {
"doc_count": 1
}
}
}
}
}

参考文档

​​https://www.elastic.co/guide/cn/elasticsearch/guide/current/aggregations.html​​


举报

相关推荐

0 条评论