elasticsearch 过滤重复_elasticsearch介绍

Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤。特别是它对多条件的过滤支持非常好。下面介绍一下为什么es在多条件查询下的性能如此出众,首先要从倒排索引开始介绍,首先看如下数据集合,每一行是一个document。每个document都有一个docid,年龄和性别属于term。

1c27f9a41bf8affa5ac9d82d69791093.png

那么给这些document建立的倒排索引如下,每一个term都会有一个倒排索引:

2d73df998113acf6fccd2c30f23d238e.png

其中[1,3]这种docid顺序排序的列表我们称为Posting list。

那当我们进行查找时,会首先基于二分查找找到对应的term,我们称这个查找树为 term dictionary。由于这个 term dictionary存储了所有的term和posting list,因此保存在磁盘上,即使二分查找加快速度,但是磁盘IO的性能远远不及内存查找,这样就引出了可以常驻在内存中的term index。

比如一本英文字典,term index只保存26个字母开头的章节信息。类似于:

70f33cc473d058e6ee9c1f0b9f63af4d.png

term index这个树可以看成是所有term的部分前缀。通过term index可以快速地定位到term dictionary的某个offset,然后从这个位置再往后顺序查找。再加上一些压缩技术(搜索 Lucene Finite State Transducers) term index 的尺寸可以只有所有term的尺寸的几十分之一,使得用内存缓存整个term index变成可能。整体上来说就是这样的效果。

76b75a31f103980490371f31d2994e41.png

那接下来是联合查询的处理,给定查询过滤条件 age=18 的过程就是先从term index找到18在term dictionary的大概位置,然后再从term dictionary里精确地找到18这个term,然后得到一个posting list。然后再查询 gender=女 的过程也是类似的。最后得出 age=18 AND gender=女 就是把两个 posting list 做一个“与”的合并。合并有两种算法:

  • 使用skip list数据结构。同时遍历gender和age的posting list,互相skip;
  • 使用bitset数据结构,对gender和age两个filter分别求出bitset,对两个bitset做AN操作。

如果查询的filter缓存到了内存中(以bitset的形式),那么合并就是两个bitset的AND。如果查询的filter没有缓存,那么就用skip list的方式去遍历两个on disk的posting list。

利用 Skip List 合并

代码如下

 public static void main(String args[]) {//初始化两个数组a,b,相当于两个倒排表 int a[]={2,4,8,16,19,23,28,43}; int b[]={1,2,3,5,8,41,51,60,71}; int c[]=new int [20];//数组用于存放相同的位置 int alen=a.length; int blen=b.length; int i=0,j=0,k=0,sk=4;//一次性跳四个 while(i=b[j+sk])//如果跳了sk个b位置仍然小于a位置 j=j+sk;//b跳sk个数字 else j++; } } for(i=0;i

使用bitset数据结构

Bitset是一种很直观的数据结构,对应posting list如:

[1,3,4,7,10]

对应的bitset就是:

[1,0,1,1,0,0,1,0,0,1]

每个文档按照文档id排序对应其中的一个bit。Bitset自身就有压缩的特点,其用一个byte就可以代表8个文档。所以100万个文档只需要12.5万个byte。但是考虑到文档可能有数十亿之多,在内存里保存bitset仍然是很奢侈的事情。而且对于个每一个filter都要消耗一个bitset,比如age=18缓存起来的话是一个bitset,18<=age<25是另外一个filter缓存起来也要一个bitset。

所以秘诀就在于需要有一个数据结构:

  • 可以很压缩地保存上亿个bit代表对应的文档是否匹配filter;
  • 这个压缩的bitset仍然可以很快地进行AND和 OR的逻辑操作。

Lucene使用的这个数据结构叫做 Roaring Bitmap。

其压缩的思路其实很简单。与其保存100个0,占用100个bit。还不如保存0一次,然后声明这个0重复了100遍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Elasticsearch 是一个分布式的开源搜索和分析引擎,它具有强大的搜索能力和高性能的数据处理能力。关于 Elasticsearch 的搜索量,没有一个具体的固定限制,它可以处理大规模的数据和高并发的搜索请求。 Elasticsearch 的性能和搜索量的处理能力取决于多个因素,包括硬件设备、集群配置、索引设计、查询复杂性等。通过适当的硬件配置、集群优化和索引优化,Elasticsearch 可以扩展到处理大规模的数据和高负载的搜索请求。 以下是一些影响 Elasticsearch 搜索量的关键因素: 1. 硬件:适当的硬件配置,包括足够的内存、磁盘空间和处理器能力,可以提供更好的性能和搜索吞吐量。 2. 集群配置:合理配置 Elasticsearch 集群的节点数量和分片数量,以适应数据量和查询负载。增加集群节点和分片可以提高搜索容量和并发性能。 3. 索引设计:优化索引结构、字段映射和分片策略,可以提高搜索效率和吞吐量。合理设置索引的副本数量,以提高搜索的可用性和负载均衡。 4. 查询优化:编写高效的查询语句,使用合适的查询类型和过滤器,减少不必要的计算和网络传输,可以提高搜索性能。 5. 缓存机制:利用 Elasticsearch 的缓存机制,如字段数据缓存、过滤器缓存和请求缓存,可以减少重复计算,提高搜索效率。 总的来说,Elasticsearch 可以处理大规模的数据和高并发的搜索请求,但要实现高性能和大搜索量的处理能力,需要综合考虑硬件、集群配置、索引设计和查询优化等各方面因素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值