[转]elasticsearch中如何高效的使用filter

标签: | 发表时间:2013-12-25 23:32 | 作者:an74520
出处:http://blog.csdn.net/an74520

这里有一篇很好的文章,很不错,翻译和整理了一下,英文不错的,建议直接看原文: http://euphonious-intuition.com/2013/05/all-about-elasticsearch-filter-bitsets/

elasticsearch里面有BOOL  、AND、OR、NOT  ,这几个看起来很相似,都有什么区别呢?什么时候用bool ?什么时候用AND filter呢?

事实上,bool filter和AND 、OR、NOT filter 是完全不同,在查询性能上面的影响是非常大的。

首先咱们需要了解的是filter里面都是怎么工作的,其中核心的一个东西叫 BitSet,可以理解为一个很大的bit数组,数组里面的每个元素有2个状态:0和1(bloom filter知道么?),而filter大家都知道,只处理文档是否匹配与否,不涉及文档评分操作。如果一个文档和filter查询匹配,那么其对应的bit位就设置为1,匹配不上则设置为0。

es在执行filter查询过滤的时候,会打开lucene的每个segment段文件,然后去判断里面的文档符合该filter与否,这个匹配的结果我们就可以用bitset来存储起来,下次同样的filter查询过来,我们就直接使用内存里面的bitset来进行判断就行了,而不需要再打开lucene的segment文件了,避免了io的操作,这样就可以大大提高查询处理的速度,这也是为什么filter这么高效的原因。

因为lucene的segment段文件是不变的,lucene会产生新段,但是旧段是不变的,所以bitset是重复利用的,根据不同的filter条件和不同的段,会产生相应的bitset,另外不同的查询可能会涉及到多个bitset的做交集,计算机对这种bit位处理过程是非常拿手的,速度很快。

另外,如果filter的结果如果是空的,那么里面的bitset位都是0,es以后在处理该filter的时候,会把该bitset整个忽略掉,提高性能。

前面说完了基础内容,咱们再看看bool filter和AND filter这些的区别吧

bool filter会使用到前面提到过的bitset数据结构(bitset派),而AND \OR\ NOTfilter则不能利用到bitset(non-bitset派),为什么呢?

AND、OR、NOT filter是doc by doc的逐个文档的处理,es逐个加载文档里面的字段内容,然后检查字段的内容是否满足查询条件,不满足的文档就排除在结果集之外,依次迭代进行,直到过完一遍所有的文档,这中间的过程用不到前面提到过的bitset,也就不能重复利用缓存资源

如果你有多个filter条件,即一个AND、OR、NOT里面包含多个filter过滤条件(支持数组的方式),那么处理的逻辑就是每个filter会将依次将生成的结果集传到下一个filter,理论上处理的文档数会越来越少,因为只会过滤减少,不会增加,这样依次过滤,所以一般限制条件比较苛刻的可以放前面执行,这样后面的filter需要处理的文档数就会很小,这样可以大大提高整体处理的速度,另外除了数量上的考虑外,还需要考虑filter的效率问题,一些filter执行效率很低,如Geo filter(大量计算)或者script based filter(动态脚本),建议将这些性能开销比较大的查询放最后执行来提高整体的处理速度。

好了,现在应该有这么一个概念了,AND、OR、NOT是文档by文档,依次处理,如果你的结果集很大,即一个很宽松的查询,命中很多,那么你使用AND、OR、NOT filter是不合适的,但是有些filter是必须文档by文档处理的,如下面的这几个filter:

  • Geo* filters
  • Scripts
  • Numeric_range

所以除了上面那几个没有办法的,其它的filter应该一律使用bool filter来提高查询性能。

如果你的查询里面需要同时使用到bitset和non-bitset类型的filter,则可以组合起来使用bool filter和AND\OR\NOT filter,

前面说了,AND 是结果集依次向后传递,所以我们把性能比较好的放前面,non-bitset放AND的filter的后面,如下面一个包含多个filter类型的复杂的filter

 

    {
  "and" :     [
        {
      "bool" :     {
        "must" :     [
              { "term" :     {    }     },
              { "range" :     {    }     },
              { "term" :     {    }     }
            ]
          }
        },
        {
      "or" :     [
            { "custom_script" :     {    }     },
            { "geo_distance" :     {    }     }
          ]
        }
      ]
    }

 

and 在最外层做wrapper,第一个filter是一个bool filter,里面有3个must的子filter,处理完了之后,得到文档结果集,然后再执行一个or的子filter,OR里面两个查询会分别进行,最终的文档结果集就是我们的搜索结果了。

总之,filter使用的时候,一定要优先使用bitset流,然后还要考虑filter顺序和组合的问题

  • Geo, Script or Numeric_range filter: 使用 And/Or/Not Filters
  • 所有其它的: 使用 Bool Filter

掌握了以上这些,就不难写出高性能的查询了。


本文出自: http://log.medcl.net/item/2013/09/elasticsearch-inside-the-various-filter/

作者:an74520 发表于2013-12-25 15:32:22 原文链接
阅读:1077 评论:1 查看评论

相关 [elasticsearch filter] 推荐:

[转]elasticsearch中如何高效的使用filter

- - an74520的专栏
这里有一篇很好的文章,很不错,翻译和整理了一下,英文不错的,建议直接看原文: http://euphonious-intuition.com/2013/05/all-about-elasticsearch-filter-bitsets/. elasticsearch里面有BOOL  filter、AND、OR、NOT  filter,这几个看起来很相似,都有什么区别呢.

Servlet Filter 学习

- - CSDN博客架构设计推荐文章
最近在研究CAS , CAS 中的Servlet Filter 不太熟悉, 所以花了点时间学下了下这部分的知识, 分成以下几部分 学习. Servlet Filter  的功能和用法. Servlet Filter 顺序的注意事项. A filter is an object that performs filtering tasks on either the request to a resource (a servlet or static content), or on the response from a resource, or both.

Servlet、Filter和Listener

- - Web前端 - ITeye博客
Java Servlet是与平台无关的服务器端组件,运行于Servlet容器中(如Tomcat),Servlet容器负责Servlet和客户端的通信以及调用Servlet的方法,Servlet和客户端的通信采用“请求/响应”的模式. Servlet可完成以下功能:. 1、创建并返回基于客户请求的动态HTML页面.

Bloom Filter 原理与应用

- - CSDN博客云计算推荐文章
Bloom Filter是一种简单的节省空间的随机化的数据结构,支持用户查询的集合. 一般我们使用STL的std::set, stdext::hash_set,std::set是用红黑树实现的,stdext::hash_set是用桶式哈希表. 上述两种数据结构,都会需要保存原始数据信息,当数据量较大时,内存就会是个问题.

dubbo中的Filter顺序

- - 互联网 - ITeye博客
最近发现dubbo的小 bug,顺便整理了一下dubbo中的Filter调用顺序及如何确定的. 服务提供方的过滤器被调用顺序:. EchoFilter->ClassLoaderFilter->GenericFilter->ContextFilter->(这4个是在代码中指定的). 服务消费方的过滤器顺序:.

activity、 intent 、intent filter、service、Broadcast、BroadcaseReceiver解释

- - CSDN博客推荐文章
Android中,Activity是所有程序的根本,所有程序的流程都运行在Activity之中,Activity具有自己的生命周期(由系统控制生命周期,程序无法改变,但可以用onSaveInstanceState保存其状态). 对于Activity,关键是其生命周期的把握(如那张经典的生命周期图=.=),其次就是状态的保存和恢复(onSaveInstanceState onRestoreInstanceState),以及Activity之间的跳转和数据传输(intent).

webservice的安全机制3---Filter

- - 博客园_首页
本节摘要:本节继续讨论webservice的安全机制,本节采用servlet的过滤器Filter来实现.    前面讲了webservice的安全机制1和2,本节继续webservice的安全之旅,.    本节采用servlet的Filter的来实现对webservice的安全访问.    在调用webservice之前,过滤器会拦截匹配的请求,只有满足安全要求的客户端才能访问webservice服务.

【转】Servlet 和filter 执行顺序

- - 企业架构 - ITeye博客
一,servlet容器对url的匹配过程:. 当一个请求发送到servlet容器的时候,容器 先会将请求的url减去当前应用上下文的路径作为servlet的映射url,比如我访问的是http://localhost/test /aaa.html,我的应用上下文是test,容器会将http://localhost/test去掉,剩下的/aaa.html部分拿来做 servlet的映射匹配.

[译]JVM上最快的Bloom filter实现

- - 鸟窝
英文原始出处: Bloom filter for Scala, the fastest for JVM. 本文介绍的是我用Scala实现的Bloom filter. 依照 性能测试结果,它是JVM上的 最快的Bloom filter实现. 零分配(Zero-allocation)和高度优化的代码.

JVM上最快的Bloom filter实现

- - ImportNew
英文原始出处:  Bloom filter for Scala, the fastest for JVM. 本文介绍的是我用Scala实现的Bloom filter. 依照 性能测试结果,它是JVM上的 最快的Bloom filter实现. 零分配(Zero-allocation)和高度优化的代码.