ElasticSearch 2 (33) - 信息聚合系列之聚合过滤
ElasticSearch 2 (33) - 信息聚合系列之聚合过滤
摘要
聚合范围限定还有一个自然的扩展就是过滤。因为聚合是在查询结果范围内操作的,任何可以适用于查询的过滤器也可以应用在聚合上。
版本
elasticsearch版本: elasticsearch-2.x
内容
聚合范围限定还有一个自然的扩展就是过滤。因为聚合是在查询结果范围内操作的,任何可以适用于查询的过滤器也可以应用在聚合上。
Filtered
查询(Filtered Query)
如果我们想找到售价在 $10,000 美元之上的所有汽车同时也为这些车计算平均售价,可以简单地使用一个 filtered
查询:
GET /cars/transactions/_search
{
"size" : 0,
"query" : {
"filtered": {
"filter": {
"range": {
"price": {
"gte": 10000
}
}
}
}
},
"aggs" : {
"single_avg_price": {
"avg" : { "field" : "price" }
}
}
}
这正如我们在前面章节中讨论过那样,从根本上讲,使用 filtered
查询和使用 match
查询没有任何区别。查询(包括了一个过滤器)返回一组文档的子集,聚合正是操作这些文档。
过滤桶(Filter Bucket)
但是如果我们只想对聚合结果过滤怎么办?假设我们正在创建一个可以搜索汽车经销商的页面,我们希望显示用户搜索的结果,但是我们同时也想在页面上提供更丰富的信息,包括(与搜索匹配的)上个月度汽车的平均售价
这里我们无法简单的做范围限定,因为有两个不同的条件。搜索结果必须是 ford
,但是聚合结果必须满足 ford
AND sold > now - 1M
。
为了解决这个问题,我们可以用一种特殊的桶,叫做过滤桶。我们可以指定一个过滤桶,当文档满足过滤桶的条件时,我们将其加入到桶内。
查询结果如下:
GET /cars/transactions/_search
{
"size" : 0,
"query":{
"match": {
"make": "ford"
}
},
"aggs":{
"recent_sales": {
"filter": { #1
"range": {
"sold": {
"from": "now-1M"
}
}
},
"aggs": {
"average_price":{
"avg": {
"field": "price" #2
}
}
}
}
}
}
#1 使用过滤桶在查询范围基础上应用过滤器。
#2 avg
度量只会对 ford
和 一月以内售出 的文档计算平均售价。
因为 filter
桶和其他桶的操作方式一样,所以可以随意将其他桶和度量嵌入其中。所有嵌套的组件都会 “继承” 这个过滤,这使我们可以按需针对聚合过滤出选择部分。
展示过滤器(Post Filter)
目前为止,我们可以同时对搜索结果和聚合结果进行过滤(一个 filtered
查询),以及针对聚合结果的一部分进行过滤(filter
桶)
我们可能会想,“有只对搜索结果进行过滤而不过滤聚合结果的方式吗?”答案是使用 post_filter
。
它是顶层搜索请求元素接收一个过滤器。这个过滤器在查询之后执行(这正是该过滤器的名字的由来:它在查询之后(post
)执行)。正因为它在查询之后执行,它对查询范围没有任何影响,所以对聚合也不会有任何影响。
我们可以利用这个行为对查询条件应用更多的过滤器,而不会影响其他的操作,就如 UI 上的各个分类面。让我们为汽车经销商设计另外一个搜索页面,这个页面允许用户搜索汽车同时可以根据颜色来过滤。颜色的选项是通过聚合获得的:
GET /cars/transactions/_search
{
"size" : 0,
"query": {
"match": {
"make": "ford"
}
},
"post_filter": { #1
"term" : {
"color" : "green"
}
},
"aggs" : {
"all_colors": {
"terms" : { "field" : "color" }
}
}
}
#1 post_filter
元素是顶层元素而且仅对命中结果进行过滤。
查询部分找到所有的 ford
汽车,然后用 terms
聚合创建一个颜色列表。因为聚合对查询范围进行操作,颜色列表与福特汽车有的颜色相对应。
最后,post_filter
会过滤搜索结果,只展示绿色福特汽车。这在查询执行过后发生,所以聚合不受影响。
这通常对 UI 的连贯一致性很重要,可以想象用户在界面商选择了一类颜色(比如:green
绿色),期望的是搜索结果已经被过滤了,而不是过滤界面上的选项。如果我们应用 filtered
查询,界面会马上变成只显示 green
作为选项,这不是用户想要的!
警告
性能考虑(Performance consideration)
只在我们需要区别过滤搜索结果和聚合结果时使用
post_filter
,有时用户会在普通搜索使用post_filter
。不要这么做!
post_filter
的特性是在查询之后执行,所以任何过滤所带来的好处(比如缓存)都会完全失去。
post_filter
应该只在我们需要不同过滤时,只与聚合一起使用。
小结(Recap)
选择合适类型的过滤(如:搜索命中、聚合或两者兼有)通常和我们期望如何表现用户交互有关。选择合适的过滤器(或组合)取决于我们期望如何将结果呈现给用户。
filtered
查询同时影响搜索结果和聚合结果。filter
桶影响聚合。post_filter
只影响搜索结果。
参考
elastic.co:
Filtering Queries and Aggregations
ElasticSearch 2 (33) - 信息聚合系列之聚合过滤的更多相关文章
- ElasticSearch - 信息聚合系列之聚合过滤
摘要 聚合范围限定还有一个自然的扩展就是过滤.因为聚合是在查询结果范围内操作的,任何可以适用于查询的过滤器也可以应用在聚合上. 版本 elasticsearch版本: elasticsearch-2. ...
- ElasticSearch 2 (37) - 信息聚合系列之内存与延时
ElasticSearch 2 (37) - 信息聚合系列之内存与延时 摘要 控制内存使用与延时 版本 elasticsearch版本: elasticsearch-2.x 内容 Fielddata ...
- ElasticSearch 2 (38) - 信息聚合系列之结束与思考
ElasticSearch 2 (38) - 信息聚合系列之结束与思考 摘要 版本 elasticsearch版本: elasticsearch-2.x 内容 本小节涵盖了许多基本理论以及很多深入的技 ...
- ElasticSearch 2 (36) - 信息聚合系列之显著项
ElasticSearch 2 (36) - 信息聚合系列之显著项 摘要 significant_terms(SigTerms)聚合与其他聚合都不相同.目前为止我们看到的所有聚合在本质上都是简单的数学 ...
- ElasticSearch 2 (35) - 信息聚合系列之近似聚合
ElasticSearch 2 (35) - 信息聚合系列之近似聚合 摘要 如果所有的数据都在一台机器上,那么生活会容易许多,CS201 课商教的经典算法就足够应付这些问题.但如果所有的数据都在一台机 ...
- ElasticSearch 2 (34) - 信息聚合系列之多值排序
ElasticSearch 2 (34) - 信息聚合系列之多值排序 摘要 多值桶(terms.histogram 和 date_histogram)动态生成很多桶,Elasticsearch 是如何 ...
- ElasticSearch 2 (32) - 信息聚合系列之范围限定
ElasticSearch 2 (32) - 信息聚合系列之范围限定 摘要 到目前为止我们看到的所有聚合的例子都省略了搜索请求,完整的请求就是聚合本身. 聚合与搜索请求同时执行,但是我们需要理解一个新 ...
- ElasticSearch 2 (31) - 信息聚合系列之时间处理
ElasticSearch 2 (31) - 信息聚合系列之时间处理 摘要 如果说搜索是 Elasticsearch 里最受欢迎的功能,那么按时间创建直方图一定排在第二位.为什么需要使用时间直方图? ...
- ElasticSearch 2 (30) - 信息聚合系列之条形图
ElasticSearch 2 (30) - 信息聚合系列之条形图 摘要 版本 elasticsearch版本: elasticsearch-2.x 内容 聚合还有一个令人激动的特性就是能够十分容易地 ...
随机推荐
- Python在自动化运维时经常会用到的方法
得到当前工作目录,即当前Python脚本工作的目录路径:os.getcwd() 返回指定目录下的所有文件和目录名:os.listdir() 函数用来删除一个文件:os.remove() 删除多个目录: ...
- Null和undefined的区别?
(1)null是一个表示”无”的对象,转我数值是为0,undefined是一个表示”无”的原始值,转为数值时为NaN.当声明的变量还未被初始化时,能量的默认值为undefined (2)Null用来表 ...
- pip install Yellowfin失败的问题
上面的方法简单有效 https://blog.csdn.net/quqiaoluo5620/article/details/80608474
- 用python2.7.9 写个小程序搜索某个目录下行有某关键字
# -*- coding: utf-8 -*-import sysreload(sys)sys.setdefaultencoding("utf-8")import os def p ...
- (转)LVS+Keepalived使用总结 vip丢失
/sbin/ifconfig lo: $vip broadcast $vip netmask 255.255.255.255 up /sbin/ifconfig lo: 172.16.254.63 b ...
- gcc 动态编译 动态库路径
gcc 动态编译(共享库) 动态编译的可执行文件需要附带一个的动态链接库,在执行时,需要调用其对应动态链接库中的命令优点:体积小,编译快缺点:依赖性高 代码如下: [root@74-82-173-21 ...
- OS X 10.11无法安装cocoapods的解决办法
前两天在给OS X 10.11 安装cocoapods时,命令行总是提示"Operation not permitted",我不管是用root用户安装还是查阅网上过去的资料都安装不 ...
- ubuntu14.04安装jupyter notebook
1.使用pip安装Jupyter notebook: pip install jupyter notebook 2.创建Jupyter默认配置文件: jupyter notebook --genera ...
- Docker的Mysql数据库:把数据存储在本地目录
Docker mysql 把数据存储在本地目录,很简单,只需要映射本地目录到容器即可 1.加上-v参数 $ docker run -d -e MYSQL_ROOT_PASSWORD=admin --n ...
- WPF编程 ,TextBlock 显示百分数值的一种简单方法。
原文:WPF编程 ,TextBlock 显示百分数值的一种简单方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/ ...