在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的理解的更多相关文章

  1. Elastic search中使用nested类型的内嵌对象

    在大数据的应用环境中,往往使用反范式设计来提高读写性能. 假设我们有个类似简书的系统,系统里有文章,用户也可以对文章进行赞赏.在关系型数据库中,如果按照数据库范式设计,需要两张表:一张文章表和一张赞赏 ...

  2. Elastic Search中Document的CRUD操作

    一. 新增Document在索引中增加文档.在index中增加document.ES有自动识别机制.如果增加的document对应的index不存在.自动创建,如果index存在,type不存在自动创 ...

  3. elastic search query & filter & query_string

    一.基本概念 1.query时,如何指定返回哪些字段 希望返回name和date字段 希望返回以location.*为前缀的字段以及date字段:不希望返回location.geolocation字段 ...

  4. Elastic Search中mapping的问题

    Mapping在ES中是非常重要的一个概念.决定了一个index中的field使用什么数据格式存储,使用什么分词器解析,是否有子字段,是否需要copy to其他字段等.Mapping决定了index中 ...

  5. Elastic Search中DSL Query的常见语法

    Query DSL是一种通过request body提交搜索参数的请求方式.就是将请求头参数(?xxx=xxx)转换为请求体参数.语法格式:GET [/index_name/type_name]/_s ...

  6. Elastic Search中normalization和分词器

    为key_words提供更加完整的倒排索引. 如:时态转化(like | liked),单复数转化(man | men),全写简写(china | cn),同义词(small | little)等. ...

  7. Elastic Search中Query String常见语法

    1 搜索所有数据timeout参数:是超时时长定义.代表每个节点上的每个shard执行搜索时最多耗时多久.不会影响响应的正常返回.只会影响返回响应中的数据数量.如:索引a中,有10亿数据.存储在5个s ...

  8. elastic search文档详解

    在elastic search中文档(document)类似于关系型数据库里的记录(record),类型(type)类似于表(table),索引(index)类似于库(database). 文档一定有 ...

  9. Elastic Search笔记

    目录 1.简介 2.概念和工具使用 2.1 基本概念 2.2 使用kibana 3.操作索引和数据 2.3 索引 2.4 索引映射到文档 2.5 新增数据 2.6 修改数据 2.7 删除数据 4. 搜 ...

随机推荐

  1. 去除ZERO WIDTH SPACE 零宽字符: 看不见却占位置的字符

    ZERO WIDTH SPACE 由于历史原因,编码方案中保留着该类编码 解决方案 1. 替换 ```js str.replace(/[\u200B-\u200D\uFEFF]/g, ''); ``` ...

  2. HDU2795线段树入门 简单查询和修改

    http://acm.hdu.edu.cn/showproblem.php?pid=2795 #include<iostream> using namespace std; ; int h ...

  3. python之ActionChains方法列表

    使用方法: 方法列表: click(on_element=None) ——单击鼠标左键 click_and_hold(on_element=None) ——点击鼠标左键,不松开 context_cli ...

  4. PHP 二维数组去重方法

    php二维数组的去重策略,如果需要根据某字段去重(其他字段可能不一致),那么需要使用循环策略,如果去重的都是相同的(字段,值),那么可以用序列化方式. $allComments = array_map ...

  5. easyUI之函数

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  6. ContentProvider 共享数据

      onCreate 其它应用第一次访问时被调. insert 外部应用使用此方法添加数据. delete 外部应用使用此方法删除数据. update 外部应用使用此方法更新数据. query 外部应 ...

  7. JS选择器querySelector和~All,三个原生选择器

    定义: querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素. 注意: querySelector() 方法仅仅返回匹配指定选择器的第一个元素.如果你需要返回所有的元素,请 ...

  8. mybaits及mybaits generator 插件使用指南(亲测原创)

    一. eclips安装mybaits插件 参考文章:http://www.cnblogs.com/zengsong-restService/archive/2013/08/09/3248245.htm ...

  9. Selenium 2自动化测试实战40(单线程)

    单线程 #onethread.py #coding:utf-8 from time import sleep,ctime #听音乐任务 def music(): print('i was listen ...

  10. CentOS 7 最小化安装后的注意事项

    http://blog.csdn.net/f_srion/article/details/54910943 在VM虚拟机中安装CentOS 7 时 有时候顾虑到电脑硬件性能,我们需要最小化安装,而最小 ...