Lucene实现倒排表没有使用bitmap,为了效率,lucene使用了一些策略,具体如下:
1. 使用FST保存词典,FST可以实现快速的Seek,这种结构在当查询可以表达成自动机时(PrefixQuery、FuzzyQuery、RegexpQuery等)效率很高。(可以理解成自动机取交集)
此种场景主要用在对Query进行rewrite的时候。
2. FST可以表达出Term倒排表所在的文件偏移。
3. 倒排表使用SkipList结构。从上面的讨论可知,求倒排表的交集、并集、差集需要各种SeekTo(docId),SkipList能对Seek进行加速。

skiplist备忘

如今大部分工具使用的倒排链已经不是简单的链表了。一个常用,比如lucene中用的,叫skiplist,是一种高效的链表结构,在查询、添加、删除的时间复杂度上做到O(logN)。数据结构如下图:

查询的过程很简单,从顶层开始,往后查询遇到节点的next()比待查的大或者到NIL了,节点不变下移一层继续向后查询,如此反复,直到到了底层还没查到。skiplist的资料也比较多,这里就不赘述了。

链表集合操作

直接引用转述这篇博文:http://www.cnblogs.com/forfuture1978/archive/2010/04/04/1704258.html  。作者很细致地把过程都列出来了,真是方便了大家啊,建议顺着读一边。

链表集合求交

lucene中用的是ConjunctionScorer ,大致过程是每条倒排链不断的推进到小于等于当前最大节点的位置。当然实现细节还是很丰富的,作者很细心的把过程都列出来了,建议顺着读一边。这里摘抄部分:

首先把倒排链按第一个next排序:

查看0~7的倒排链的第一个和最后一个是否相同,不同就开始找;取最后一个倒排的第一个元素8作为终点, 第一个链表开始找8

第0个链表 跳过1到了10,那么8也不用找了都去找10就行了

第1根链表找到了11,那么10也不用找了,找11,之后都这么做

......

之后遇到11,本次交集操作找到一个11,

后续的计算也是同理,当然整个代码实现会比较复杂和讨巧。基本思路就是每条倒排链能根据当前文档迅速跳过不符合的docid,由于倒排链可以用skiplist查询,因此即使很长的倒排链,如果交集的数量很少,整个求解过程可以很快跳过不需要比较的节点。

Lucene核心数据结构——FST存词典,跳表存倒排或者roarning bitmap 见另外一个文章的更多相关文章

  1. 聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)

    redis使用跳表不用B+数的原因是:redis是内存数据库,而B+树纯粹是为了mysql这种IO数据库准备的.B+树的每个节点的数量都是一个mysql分区页的大小(阿里面试) 还有个几个姊妹篇:介绍 ...

  2. 自己动手实现java数据结构(九) 跳表

    1. 跳表介绍 在之前关于数据结构的博客中已经介绍过两种最基础的数据结构:基于连续内存空间的向量(线性表)和基于链式节点结构的链表. 有序的向量可以通过二分查找以logn对数复杂度完成随机查找,但由于 ...

  3. lucene底层数据结构——FST,针对field使用列存储,delta encode压缩doc ids数组,LZ4压缩算法

    参考: http://www.slideshare.net/lucenerevolution/what-is-inaluceneagrandfinal http://www.slideshare.ne ...

  4. lucene .doc里存储的skiplist跳表

    http://forfuture1978.iteye.com/blog/546841 见图: lucene-6.5.1-src/lucene-6.5.1$ grep "skiplistwri ...

  5. ES索引文件和数据文件大小对比——splunk索引文件大小远小于ES,数据文件的压缩比也较ES更低,有趣的现象:ES数据文件zip压缩后大小和splunk的数据文件相当!词典文件tim/tip+倒排doc/pos和cfs文件是索引的大头

    和splunk对比: ES中各个倒排索引文件的分布: 测试说明:ES2.41版本,数据使用500次批量插入,每批数据都不同,大小500条,每条数据50个字段,对应的字符串使用长度为1-10个单词随机生 ...

  6. skiplist(跳表)的原理及JAVA实现

    前记 最近在看Redis,之间就尝试用sortedSet用在实现排行榜的项目,那么sortedSet底层是什么结构呢? "Redis sorted set的内部使用HashMap和跳跃表(S ...

  7. [转载] 跳表SkipList

    原文: http://www.cnblogs.com/xuqiang/archive/2011/05/22/2053516.html leveldb中memtable的思想本质上是一个skiplist ...

  8. 跳表SkipList

    原文:http://www.cnblogs.com/xuqiang/archive/2011/05/22/2053516.html 跳表SkipList   1.聊一聊跳表作者的其人其事 2. 言归正 ...

  9. C语言跳表(skiplist)实现

    一.简介 跳表(skiplist)是一个非常优秀的数据结构,实现简单,插入.删除.查找的复杂度均为O(logN).LevelDB的核心数据结构是用跳表实现的,redis的sorted set数据结构也 ...

随机推荐

  1. vue打包后.woff字体文件路径问题处理

    在执行 npm run build 命令打包后,如果出现 .woff 等字体文件找不到的情况 通过设置 vue-style-loader 打包前缀路径解决

  2. java输出月的日历控制台

    LocalDate date=LocalDate.now(); int month=date.getMonthValue(); int today=date.getDayOfMonth(); date ...

  3. nginx 之 https 证书配置

    HTTPS原理和作用 为什么需要HTTPS 原因:HTTP不安全 传输数据被中间人盗用.信息泄露 数据内容劫持.篡改 HTTPS协议的实现 对传输内容进行加密以及身份验证 对称加密:加密秘钥和解密秘钥 ...

  4. python之反射机制与callattr()、issubclass()、isinstance、type()相关

    一.反射机制 * 反射可以理解为 通过字符串的形式,动态导入模块: 利用字符串的形式,在对象(模块)中操作(查找/获取/删除/添加)成员,是一种基于字符串的事件驱动! 反射机制的内置函数 # hasa ...

  5. mr-robot靶机练习

    在业余时间进行的靶机练习,也是根据网上的大牛做下来的,重复造轮子吧,但是个人感觉还是即使是造轮子也是需要自己动手呀,毕竟每个人做的过程中遇到的问题是不一样的,这样既可以帮助别人也能锻炼自己.希望可以帮 ...

  6. 关于MQ的几件小事(二)如何保证消息队列的高可用

    1.RabbitMQ的高可用 RabbitMQ基于主从模式实现高可用.RabbitMQ有三种模式:单机模式,普通集群模式,镜像集群模式. (1)单机模式: 单机模式就是demo级别的,生产中不会有人使 ...

  7. opencv 图片识别

    # -*- coding: utf-8 -*-"""Created on Fri Nov 22 21:35:12 2019 @author: Administrator& ...

  8. java基础(4)---引用数据类型(数组、字符串、集合)

    一.数组 格式: int[] nums; 1. 数据类型[] 数组名称; 2. 数据类型 数组名称[]; (不太推荐)  动态初始化: new int[4] 数据类型[] 数组名称 = new 数据类 ...

  9. 稀疏矩阵在Python中的表示方法

    对于一个矩阵而言,若数值为零的元素远远多于非零元素的个数,且非零元素分布没有规律时,这样的矩阵被称作稀疏矩阵:与之相反,若非零元素数目占据绝大多数时,这样的矩阵被称作稠密矩阵. 稀疏矩阵在工程应用中经 ...

  10. linux网络编程之posix信号量与互斥锁

    继上次学习了posix线程之后,这次来讨论一下posix信号量与互斥锁相关的知识: 跟posix消息队列,共享内存的打开,关闭,删除操作一样,不过,上面的函数是对有名信号量进行操作,通过man帮助可以 ...