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

简介: 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

相关文章
如何对数组进行一个过滤操作map
如何对数组进行一个过滤操作map
83 0
es聚合查询并且返回对应组的数据
es聚合查询并且返回对应组的数据
439 0
|
6月前
|
关系型数据库 分布式数据库 PolarDB
使用 PolarDB 开源版 bloom filter index 实现任意字段组合条件过滤
背景PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力.本文将介绍使用 PolarDB 开源版 bloom filter index 实现任...
123 0
|
存储
Elastic实战: 通过bucket_sort针对聚合后结果实现分页、排序
elaticsearch中实现聚合操作十分常见,同时es本身存储的数据量一般都比较大,因此聚合结果数量通常都比较多,所以针对聚合结果进行分页,也是非常常见的需求
613 0
Elastic实战: 通过bucket_sort针对聚合后结果实现分页、排序
|
关系型数据库 MySQL
ES复杂查询-结果过滤, 排序,分页
ES复杂查询-结果过滤, 排序,分页
|
存储 SQL 关系型数据库
ES聚合查询详解(二):桶聚合
ES聚合查询详解(二):桶聚合
467 0
ES聚合查询详解(二):桶聚合
|
SQL 关系型数据库 MySQL
ES中如何实现类似having的先聚合再过滤查询
ES中如何实现类似having的先聚合再过滤查询
550 0
ES中如何实现类似having的先聚合再过滤查询
|
存储 SQL 并行计算
使用 PolarDB 开源版 bloom filter index 实现任意字段组合条件过滤
PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力. 本文将介绍使用 PolarDB 开源版 bloom filter index 实现任意字段组合条件过滤
267 0
|
Ubuntu Java 程序员
Elasticsearch聚合的嵌套桶如何排序
在elasticsearch的聚合查询中,经常对聚合的数据再次做聚合处理,这样的聚合结果如何进行排序呢,本文将对此展开讨论和实践
328 0
Elasticsearch聚合的嵌套桶如何排序
|
缓存 索引
ES聚合查询详解(一)
ES聚合查询详解(一)
622 0