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. 搜 ...
随机推荐
- Python选择指定文件夹的文件然后复制出其中几个文件到新的文件夹
""" 要求: 1.读取cdm文件的所有子文件夹,然后每个文件夹里面是抽出一个一个mp3后缀的文件. 遍历所有的子文件,然后将这些mp3文件,保存到一个新的文件夹.文件夹 ...
- js 继承的一个例子
<script type="text/javascript"> function Animal(){ this.species = "动物"; th ...
- Content:"\2715",特殊字符和图标
原文 项目中用到的一些特殊字符和图标 html代码 <div class="cross"></div> css代码 1 2 3 4 5 6 7 8 9 10 ...
- ArcGIS Python 坐标系信息
############################################################# import arcpy import os from arcpy impo ...
- POJ 1135 -- Domino Effect(单源最短路径)
POJ 1135 -- Domino Effect(单源最短路径) 题目描述: 你知道多米诺骨牌除了用来玩多米诺骨牌游戏外,还有其他用途吗?多米诺骨牌游戏:取一 些多米诺骨牌,竖着排成连续的一行,两 ...
- [Java]简单计算下一段Java代码段运行了多少秒
long startTime = System.currentTimeMillis(); ...... long endTime = System.currentTimeMillis(); logge ...
- react 闲谈
从事前端一段时间了,公司用的框架都是vue,但是不知为何对react却情有独钟,这是不是所谓的吃着碗里的看着锅里的 哈哈哈 从头好好总结下react吧 小白一个 大神勿喷 瞎说一 react是由两部分 ...
- 性能测试 | Web端性能测试
这篇文章想跟大家分享关于Web性能测试的一些知识点.在分享之前,我想先跟大家分享一组数据,关于为什么要做性能测试?具体如下: 71%用户希望在手机上打开网页能跟电脑一样快: 5秒钟被认为是用户能忍受的 ...
- Ubuntu下使用AMD APP编写OpenCL程序
对于Ubuntu或其近亲(Lubuntu.Kubuntu.Mint等)编写OpenCL程序也不会太难.由于本例用的是AMD APP SDK,因此需要AMD的GPU以及相关驱动.首先,去AMD官网下载G ...
- 进程对列,生产者和消费者,JoinableQueue
1.进程对列 让进程之间共享资源 先进先出 (1)基本语法 from multiprocessing import Process,Queue q = Queue() # 1.用put方法往队列中存值 ...