过滤查询以及聚合

A natural extension to aggregation scoping is filtering. Because the aggregation operates in the context of the query scope, any filter applied to the query will also apply to the aggregation. 过滤是聚合作用域的一个很自然的扩展。因为聚合工作在查询作用域的上下文中,那么适用于查询的任何过滤器也同样能够适用于聚合。

filtered查询

如果你想要找到所有售价高于10000美刀的车,同时也对这些车计算其平均价格,那么可以使用一个filtered查询:

GET /cars/transactions/_search?search_type=count
{
"query" : {
"filtered": {
"filter": {
"range": {
"price": {
"gte": 10000
}
}
}
}
},
"aggs" : {
"single_avg_price": {
"avg" : { "field" : "price" }
}
}
}

从本质上而言,使用filtered查询和使用match查询并无区别,正如我们在上一章所讨论的那样。该查询(包含了一个过滤器)返回文档的一个特定子集,然后聚合工作在该子集上。

过滤桶(Filter Bucket)

如果你只想过滤聚合结果呢?假设我们正在创建针对汽车交易的搜索页面,我们想要根据用户搜索内容来展示对应结果。但是我们也想通过包含上个月出售的汽车的平均价格(匹配搜索的汽车)来让页面更加丰富。

此时我们不能使用简单的作用域,因为有两个不同搜索条件。搜索结果必须要匹配ford,但是聚合结果必须要匹配ford以及售出时间为上个月。

为了解决这一问题,我们使用一个名为filter的特殊桶。通过制定一个过滤器,当文档匹配了该过滤器的规则时,它就会被添加到桶中。

以下是得到的查询:

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

因为过滤器桶和任何其它桶以相似的方式工作,你可以任意地将其它桶和指标包含在其中。所有的嵌套组建都会”继承”该过滤器。从而使你能够根据需要对聚合中的内容进行过滤。

后置过滤器(Post Filter)

目前,我们有了用于过滤搜索结果和聚合的过滤器(filtered查询),也有了用于过滤聚合中某一部分的过滤器(filter桶)。

你也许会好奇,“是否有一种过滤器只过滤搜索结果,而不过滤聚合呢?”这个问题的答案就是使用post_filter。

它是搜索请求内能够接受一个过滤器作为参数的顶层元素。该过滤器会在查询执行完毕后生效(后置因此得名:在查询执行之后运行)。正因为它在查询执行后才会运行,所以它并不会影响查询作用域 - 因此就不会对聚合有所影响。

我们可以利用这一行为在搜索条件中添加额外的过滤器,而不影响用户界面中类似于类别分面(Categorical Facets)的元素。让我们设计另一个针对汽车交易的搜索页面。该页面允许用户对汽车进行搜索,同时还能够根据颜色进行过滤。颜色通过聚合提供:

GET /cars/transactions/_search?search_type=count
{
"query": {
"match": {
"make": "ford"
}
},
"post_filter": {
"term" : {
"color" : "green"
}
},
"aggs" : {
"all_colors": {
"terms" : { "field" : "color" }
}
}
}

post_filter元素是一个顶层元素,只会对搜索结果进行过滤。

查询部分呢用来找到所有ford汽车。然后我们根据一个terms聚合来得到颜色列表。因为聚合是在查询作用域中进行的,得到的颜色列表会反映出ford汽车的各种颜色。

最后,post_filter会对搜索结果进行过滤,只显示绿色的ford汽车。这一步发生在执行查询之后,因此聚合是不会被影响的。

这一点对于维持一致的用户界面而言是非常重要的。假设一个用户在界面上点击了一个分类(比如,绿色)。期望的结果是搜索结果被过滤了,而用户界面上的分类选项是不会变化的。如果你使用了一个filtered查询,用户界面上也立即会对分类进行更新,此时绿色就变成了唯一的选项 - 这显然不是用户想要的!

警告:性能考量

只有当你需要对搜索结果和聚合使用不同的过滤方式时才考虑使用post_filter。有时一些用户会直接在常规搜索中使用post_filter。

不要这样做!post_filter会在查询之后才会被执行,因此会失去过滤在性能上帮助(比如缓存)。

post_filter应该只和聚合一起使用,并且仅当你使用了不同的过滤条件时。

总结

选择合适类型的过滤 - 搜索结果(Search Hits),聚合(Aggregations),或两者 - 通常都取决于你的用户界面的行为。过滤器的选择(或者组合)取决于你想要如何向用户展示结果数据。

A filtered query affects both search results and aggregations.filtered查询会影响搜索结果和聚合。 

filter桶只影响聚合。 

post_filter只影响搜索结果。

elasticsearch 深入 —— Post Filter后置过滤器的更多相关文章

  1. angular内置过滤器-filter

    这篇文章来讲解一下angular内置的filter过滤器. 没错,这个过滤器的名字,就叫'filter',虽然自定义过滤器也是使用module.filter()...但是不要混淆了,这个filter就 ...

  2. Asp.Netcore使用Filter来实现接口的全局异常拦截,以及前置拦截和后置拦截

    原文链接:https://blog.csdn.net/qq_38762313/article/details/85234594 全局异常拦截器:       解决写每个接口都需要去做容错而添加try{ ...

  3. apache shiro内置过滤器 标签 注解

    内置过滤器 anon(匿名)  org.apache.shiro.web.filter.authc.AnonymousFilter authc(身份验证)       org.apache.shiro ...

  4. 009-spring cloud gateway-过滤器GatewayFilter、GlobalFilter、GatewayFilterChain、作用、生命周期、GatewayFilterFactory内置过滤器

    一.概述 在Spring-Cloud-Gateway之请求处理流程中最终网关是将请求交给过滤器链表进行处理. 核心接口:GatewayFilter,GlobalFilter,GatewayFilter ...

  5. 2.3 spring5源码系列---内置的后置处理器PostProcess加载源码

    本文涉及主题 1. BeanFactoryPostProcessor调用过程源码剖析 2. 配置类的解析过程源码 3. 配置类@Configuration加与不加的区别 4. 重复beanName的覆 ...

  6. Angular.js之内置过滤器学习笔记

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  7. Spring(二)--FactoryBean、bean的后置处理器、数据库连接池、引用外部文件、使用注解配置bean等

    实验1:配置通过静态工厂方法创建的bean  [通过静态方法提供实例对象,工厂类本身不需要实例化!] 1.创建静态工厂类 public class StaticFactory { private st ...

  8. AngularJS复习-----内置过滤器和内置服务

    AngularJS中的内置服务(共30多个): $http 发送http请求,主要用于进行异步数据请求的功能实现,这个服务主要封装了XMLHttpRequest对象和JSONP数据访问模式来完成远程请 ...

  9. map内置函数、lambda表达式、快捷生成想要的列表、filter内置函数

      map函数                             语法 map(function, iterable, ...) 参数 function -- 函数,有两个参数 iterable ...

随机推荐

  1. error: must use ‘class’ tag to refer to type ‘XXX’ in this scope

    开发环境: Qt Creator 4.8.2 在写程序的时候,遇到了编译器报错 error: must use 'class' tag to refer to type 'XXX' in this s ...

  2. 树形dp专栏

    前言 自己树形dp太菜了,要重点搞 219D Choosing Capital for Treeland 终于自己做了一道不算那么毒瘤的换根dp 令 \(f[u]\) 表示以 \(u\) 为根,子树内 ...

  3. poj 3468 : A Simple Problem with Integers 【线段树 区间修改】

    题目链接 题目是对一个数组,支持两种操作 操作C:对下标从a到b的每个元素,值增加c: 操作Q:对求下标从a到b的元素值之和. #include<cstdio> #include<c ...

  4. 预览下载的pdf的——pdf.js

    1.需要到官网下载源码:https://mozilla.github.io/pdf.js/ 2. function(){ let url='./demo1.pdf'; window.location. ...

  5. Jmeter参数化控件意见收集

    1.可以读取EXCEL,可以自定义SHEET,行和列: 2.数据可以加密传输,加密方式如下: 1)SHA1 2)SHA224 3)SHA256 4)SHA384 5)SHA512 6)MD5 7)Hm ...

  6. C# 与 C++,语法差别有多小-第二章 C++浏览

    (一)动态内存分配和指针 C++:new  和 delete                                  int *arr = new int[ 4 ]; C#:只有new,de ...

  7. (1)消灭初级程序员常用的多层if-else嵌套--------------【表驱动法】

    表驱动法 1.相信很多刚从事工作的程序员或一些初级程序员在写代码的时候会出现对一些逻辑判断写成多层if-else嵌套的经历,这种方式在一些简单的层次中运用起来确实可行,但对于一些大型项目逻辑判断比较多 ...

  8. 用ASP实现文件下载

    <% '**************************************************************'**使用方法:                        ...

  9. [CF1056E]Check Transcription

    题目:Check Transcription 传送门:http://codeforces.com/contest/1056/problem/E 分析: 1)显然有个$O( \frac{t}{max(c ...

  10. php常见五种设计模式

    php面向对象基础知识 请点击查看 一.常见的设计模式主要有23种,根据使用目标的不同可以分为以下三大类:创建设计模式.结构设计模式.行为模式创建设计模式: (5种)用于创建对象时的设计模式.初始化对 ...