Elastic Search中filter的理解
在ES中,请求一旦发起,ES服务器是按照请求参数的顺序依次执行具体的搜索过滤逻辑的。如何定制请求体中的搜索过滤条件顺序,是一个经验活。
类似query(指search中的query请求参数),也是搜索的一种方式。与常见的搜索对比,filter不会计算搜索条件相关度分数,也不会根据相关度分数进行排序,相对效率更高一些。且filter内置cache,自动缓存常用的filter数据,有效提升过滤速度。语法:
GET /test_sort/_search
{
"query": {
"bool": {
"filter": {
"range": {
"order": {
"lt" : 20
}
}
},
"must": [
{
"match": {
"content": "second"
}
}
]
}
}
}
如果搜索数据需要对相关度进行排序,如百度搜索,使用搜索查询。如果搜索数据对相关度无要求,建议使用filter来提升执行效率。通常来说,如果有多个条件的话,一般都会使用其中的部分条件做filter过滤,再执行query搜索,来提高效率。
如果是单纯的过滤数据。不需要增加额外的搜索匹配(没有任何的相关度分数计算的要求),也可以使用下述语句:
GET /test_sort/_search
{
"query": {
"constant_score": {
"filter": {
"range": {
"order": {
"lte": 20
}
}
}
}
}
}
5.1 fitler 底层执行原理(bitset机制和cache机制)
5.1.1 执行流程
首先我们假设某index中有document数据如下:
POST /_bulk
{ "create" : { "_index" : "test_filter" , "_type" : "filter_type", "_id" : "1" } }
{"field" : "2011 2012 2013"}
{ "create" : { "_index" : "test_filter" , "_type" : "filter_type", "_id" : "2" } }
{"field" : "2012 2013 2014"}
{ "create" : { "_index" : "test_filter" , "_type" : "filter_type", "_id" : "3" } }
{"field" : "2013 2014 2015"}
{ "create" : { "_index" : "test_filter" , "_type" : "filter_type", "_id" : "4" } }
{"field" : "2012 2014 2011"}
{ "create" : { "_index" : "test_filter" , "_type" : "filter_type", "_id" : "5" } }
{"field" : "2011 2012 2014"}
{ "create" : { "_index" : "test_filter" , "_type" : "filter_type", "_id" : "6" } }
{"field" : "2014 2012 2011"}
那么ES会创建的倒排索引如下:
Word Docs
"2011" 1, 4, 5, 6
"2012" 1, 2, 4, 5, 6
"2013" 1, 2, 3
"2014" 2, 3, 4, 5, 6
"2015" 3
当filter条件如下:
GET /test_filter/filter_type/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"field": "2011"
}
}
}
}
}
那么这个Filter的执行流程是:
5.1.1.1 搜索
在倒排索引中查找搜索串,获取document list,此时根据搜索结果得出,符合条件的document list是id为1,4,5,6的document。
5.1.1.2 构建bitset
ES会为每个filter在倒排索引中搜索得到的结果构建一个bitset。bitset很简单,就是一个二进制的数组,数组下标对应的是当前index中document的搜索顺序(不是任何的排序,就是ES存储的顺序,也是查询的基础顺序,可以通过一个全搜索获取index的存储顺序。在现在的案例中,存储顺序为id:5、2、4、6、1、3),如我们的案例中,document总计有6个,假设ES的存储顺序就是5、2、4、6、1、3,那么bitset的下标0~5分别对应id为1~6的document。构建的bitset长度就是6。在bitset中,0代表不符合搜索条件,1代表符合搜索条件,那么我们的搜索结果对应的bitset就是:[1, 0, 1, 1, 1, 0]。ES使用bitset来标记document是否符合搜索条件,也是为了用最简单的数据结构来描述搜索结果,来节省内存的开销。
5.1.1.3 遍历bitset
因为一个搜索中可以有多个filter条件,搜索在ES执行后,filter对应的bitset可能有多个,ES会遍历每个filter对应的bitset,且从最稀疏的开始遍历,以达到效率最佳。
最稀疏代表bitset中的1最少,1最少代表这个bitset中符合搜索条件的数据最少,从这个bitset开始遍历,可以尽可能的一次性过滤掉最多的不符合条件的document。
当所有的bitset遍历结束后,所有的filter条件过滤完成。得到过滤结果。
Filter 2011 [1,0,1,1,1,0] -> 有4个1,代表有4条数据符合过滤条件
Filter 2012 [1,0,0,0,1,1] -> 有3个1,代表有3条数据符合过滤条件
先从filter2012的bitset开始迭代。因为可以一次性过滤掉3个不符合过滤条件的数据。
5.1.1.4 caching bitset
ES会缓存bitset数据到内存中,如果后续的搜索语法中,有相同的filter条件,那么从缓存中直接使用对应的bitset来过滤数据,效率最优。
ES也不是所有的bitset都缓存,其缓存机制是:最近的256个filter中,如果某个filter执行次数达到一定的数量,则缓存bitset。(一定的数量不是固定的,是有一定逻辑算法的,如:10秒内搜索10次,20秒内搜索30次, 50秒内搜索100次)
ES也有不缓存的bitset:如果数据少于1000则不缓存(index中的ducument少于1000)。如果索引分段数据不足索引整体数据的3%也不缓存。(索引分段在后续课程中详细讲解,现在简单理解为索引的一部分,简单理解为一个shard)
因为这个bitset的缓存,所以filter的执行效率是比query高的。
这个时候,搜索结果已经返回。ES在缓存bitset的同时,一般已经返回了搜索结果了。也就是一个并发的操作,搜索完成返回结果和缓存bitset同时执行。
5.1.2 执行特性
当多次filter搜索的时候,中间掺杂了数据的写入操作,那么缓存在内存中的bitset是否就是错误的?ES在filter执行过程中,也有其特性,用于解决上述问题。
5.1.2.1 query和filter的执行顺序
一般来说,ES会先执行filter,再执行query,因为filter效率高,能够过滤掉不符合搜索条件的数据。且query是需要计算相关度分数来排序的,执行效率低,如果先执行query,会导致不符合filter过滤条件的数据也参与了相关度分数计算和排序,效率降低。
5.1.2.2 bitset cache auto_update
如果document的数据修改,或新增、删除了document,那么缓存的bitset会自动更新,保证缓存bitset的数据有效性。这个自动更新是ES自动操作的,不需要关心。
ES实现bitset cache auto_update就是为了解决缓存数据与存储数据不一致的问题。
5.1.2.3 bitset cache的应用时机
只要在ES中执行query的时候包含filter过滤条件,ES都会先检查cache中是否有这个filter的bitset cache,如果有,则直接使用,如果没有,则搜索过滤index中的document。
Elastic Search中filter的理解的更多相关文章
- Elastic search中使用nested类型的内嵌对象
在大数据的应用环境中,往往使用反范式设计来提高读写性能. 假设我们有个类似简书的系统,系统里有文章,用户也可以对文章进行赞赏.在关系型数据库中,如果按照数据库范式设计,需要两张表:一张文章表和一张赞赏 ...
- Elastic Search中Document的CRUD操作
一. 新增Document在索引中增加文档.在index中增加document.ES有自动识别机制.如果增加的document对应的index不存在.自动创建,如果index存在,type不存在自动创 ...
- elastic search query & filter & query_string
一.基本概念 1.query时,如何指定返回哪些字段 希望返回name和date字段 希望返回以location.*为前缀的字段以及date字段:不希望返回location.geolocation字段 ...
- Elastic Search中mapping的问题
Mapping在ES中是非常重要的一个概念.决定了一个index中的field使用什么数据格式存储,使用什么分词器解析,是否有子字段,是否需要copy to其他字段等.Mapping决定了index中 ...
- Elastic Search中DSL Query的常见语法
Query DSL是一种通过request body提交搜索参数的请求方式.就是将请求头参数(?xxx=xxx)转换为请求体参数.语法格式:GET [/index_name/type_name]/_s ...
- Elastic Search中normalization和分词器
为key_words提供更加完整的倒排索引. 如:时态转化(like | liked),单复数转化(man | men),全写简写(china | cn),同义词(small | little)等. ...
- Elastic Search中Query String常见语法
1 搜索所有数据timeout参数:是超时时长定义.代表每个节点上的每个shard执行搜索时最多耗时多久.不会影响响应的正常返回.只会影响返回响应中的数据数量.如:索引a中,有10亿数据.存储在5个s ...
- elastic search文档详解
在elastic search中文档(document)类似于关系型数据库里的记录(record),类型(type)类似于表(table),索引(index)类似于库(database). 文档一定有 ...
- Elastic Search笔记
目录 1.简介 2.概念和工具使用 2.1 基本概念 2.2 使用kibana 3.操作索引和数据 2.3 索引 2.4 索引映射到文档 2.5 新增数据 2.6 修改数据 2.7 删除数据 4. 搜 ...
随机推荐
- 使用editcap.exe分割pcap文件
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- ARP输入 之 arp_rcv
概述 arp_rcv是ARP包的入口函数,ARP模块在二层注册了类型为ETH_P_ARP的数据包回调函数arp_rcv,当收到ARP包时,二层进行分发,调用arp_rcv: arp_rcv对ARP输入 ...
- polya置换
UVA10294 POLYA定理的基本应用 题意:有n个珠子围成的环,有t种颜色可以染这些珠子:如果这个环可以旋转有几种办法:如果这个环可以旋转,且可以翻转,有几种办法: 参考博客 刘汝佳的分析: 等 ...
- spark 常用函数介绍(python)
以下是个人理解,一切以官网文档为准. http://spark.apache.org/docs/latest/api/python/pyspark.html 在开始之前,我先介绍一下,RDD是什么? ...
- Linux系统是否被植入木马的排查流程梳理
在日常繁琐的运维工作中,对linux服务器进行安全检查是一个非常重要的环节.今天,分享一下如何检查linux系统是否遭受了入侵? 一.是否入侵检查 1)检查系统日志 1 2 检查系统错误登陆日志,统计 ...
- Android即时通讯开发之XMPP (一)初识XMPP协议和asmack
在讲XMPP和asmck之前 ,我还是先分享一些资源文档,如果你有耐心,可以直接忽略我下面所写的.下面有关XMPP的介绍大部分是摘抄网上的文档,后面我会写一些基于XMPP协议和asmck开源库的聊天室 ...
- SpringCloud(一)之微服务核心组件Eureka(注册中心)的介绍和使用
一 Eureka服务治理体系1.1 服务治理服务治理是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册和发现. Spring Cloud Eureka是Spring Clou ...
- ceph报错
[ceph_deploy.mon][ERROR ] RuntimeError: config file /etc/ceph/ceph.conf exists with different conten ...
- 手写web框架之加载Controller,初始化框架
1,加载Controller 我们需要创建 一个ControllerHelper类,让它来处理下面的逻辑: 通过ClassHelper我们可以获取所有定义了Controller注解的 ...
- C#创建windows服务(一:初识windows服务)
一 . 服务简介 Microsoft Windows 服务(过去称为 NT 服务)允许用户创建可在其自身的 Windows 会话中长时间运行的可执行应用程序. 这些服务可在计算机启动时自动启动,可以暂 ...