过滤桶 (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