Elasticsearch Filter执行原理

Filter执行原理

  • 一. 执行流程
    • 1.1 构建bitset
    • 1.2 遍历bitset
    • 1.3 缓存bitset
  • 二. 执行特性
    • 2.1 query和filter的执行顺序
    • 2.2 bitset cache auto_update
    • 2.3 bitset cache应用的时机

序号 内容 链接地址
1 SpringBoot整合Elasticsearch7.6.1 https://blog.csdn.net/miaomiao19971215/article/details/105106783
2 Elasticsearch Filter执行原理 https://blog.csdn.net/miaomiao19971215/article/details/105487446
3 Elasticsearch 倒排索引与重建索引 https://blog.csdn.net/miaomiao19971215/article/details/105487532
4 Elasticsearch Document写入原理 https://blog.csdn.net/miaomiao19971215/article/details/105487574
5 Elasticsearch 相关度评分算法 https://blog.csdn.net/miaomiao19971215/article/details/105487656
6 Elasticsearch Doc values https://blog.csdn.net/miaomiao19971215/article/details/105487676
7 Elasticsearch 搜索技术深入 https://blog.csdn.net/miaomiao19971215/article/details/105487711
8 Elasticsearch 聚合搜索技术深入 https://blog.csdn.net/miaomiao19971215/article/details/105487885
9 Elasticsearch 内存使用 https://blog.csdn.net/miaomiao19971215/article/details/105605379
10 Elasticsearch ES-Document数据建模详解 https://blog.csdn.net/miaomiao19971215/article/details/105720737

filter底层原理涉及到两块内容: bitset机制和cache机制。

一. 执行流程

假设现在有一批数据的倒排索引如下:

Word Docs
2016 1,4,5,6
2017 1,2,4,5,6
2018 1,2,3
2019 2,3,4,5,6
2020 5

搜索时,使用的filter条件如下:

GET /search
{
   "query": {
        "constant_score": {
                 "filter": {
                     "term": {
                          "field": 2016
                     }
                 }
        }
    }
}

1.1 构建bitset

首先,ES会从index的倒排索引中遍历Word,找到2016对应的符合搜索条件的Docs——“1,4,5,6”。
接着,ES会将"1,4,5,6"构造成一个bitset。bitset是一个二进制数组,数组的下标对应着document数据存储(插入)的顺序,数组的容量由document的数量来决定,在bitset中,0代表不符合搜索条件,1代表符合搜索条件。
比如本例中,ES将会构建一个容量为6的二进制数组,假设document插入的顺序为5,2,4,6,1,3,那么当前filter对应的bitset数组内的组成情况是: [1,0,1,1,1,0]

1.2 遍历bitset

一次搜索中,可能会出现多个filter,每一个filter都会对应一个bitset。ES会从最稀疏的bitset开始遍历,以达到最佳的执行效率。
bitset的稀疏性指的是包含符合过滤条件的document的数量,可以从bitset数组内1的数量体现出来。比如[1,0,1,1,1,0] 就比[1,1,1,1,1,1,]要更稀疏。
为什么从最稀疏的bitset开始过滤?因为过滤的目的是为了筛选出符合条件的数据,丢弃无用的数据。bitset越稀疏,代表筛选条件越严格,本次过滤的垃圾数据就越多。
ES5中,query内不能直接连接filter,query和filter之间需要通过bool来间隔。ES7中,and不能写在query中,所以坦白说,目前我没有发现一次搜索中出现多个filter的写法。况且完全可以在一个filter内通过bool条件达到写多个过滤条件的目前,因此没必要写多个filter

1.3 缓存bitset

ES会缓存bitset数据到内存中,如果后续的搜索语句中filter过滤条件在之前已经使用过,那么ES会从缓存中直接找到对应的bitset,并根据bitset数组的内容,直接通过_id搜索目标document并返回结果集。ES缓存的是bitset数组,而不是通过filter搜索出的结果。
不是所有的bitset都会被ES缓存到内存中,不进行缓存的bitset大致分为以下两种情况:
情况1: 整个index内存储document的数量不足1000条。
情况2: 索引分段后的数据不足索引中所有数据的3%。
正是因为bitset缓存,使得filter的执行效率比不使用filter时query要高。
注意: ES在缓存bitset的同时,会返回搜索结果。换句话说,"缓存"和"根据bitset的内容查询、返回结果集"这两步操作是并发执行的。

二. 执行特性

2.1 query和filter的执行顺序

一般来说,ES会优先执行filter,,通过filter过滤掉一部分不符合搜索条件的数据,再执行query。况且query需要计算相关度分数来进行排序,因此执行效率低。如果先执行query,那么就会把那些不符合搜索条件的数据也进行了相关度分数计算,浪费性能。

2.2 bitset cache auto_update

ES缓存的bitset后,不会置之不理。如果有修改、新增、删除操作,导致原先fitler对应的bitset结构或内容发生变化时,ES会及时的更新内存中缓存的bitset,值得注意的是,这个更新操作由ES自动完成。

2.3 bitset cache应用的时机

只要ES中执行的query内包含filter,那么ES首先就会在缓存中搜索该filter条件是否曾经执行过,有没有对应的bitset缓存存在,若有,则使用缓存,若没有,则创建bitset,查询、返回数据,同时缓存bitset。

你可能感兴趣的:(#,分布式搜索引擎)