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. ol li 兼容

    ol 标签在 chrome 60 和 safari12 缩进不一样. 因为序号距离copy距离不一样,导致显示不一样.解决办法. list-style-position: inside;text-in ...

  2. body onload()事件和table insertRow()、tr insertCell()

    onload事件: 定义和用法: onload 事件会在页面或图像加载完成后立即发生. onload 通常用于 <body> 元素,在页面完全载入后(包括图片.css文件等等.)执行脚本代 ...

  3. SVM-支持向量机总结

    一.SVM简介 (一)Support Vector Machine 支持向量机(SVM:Support Vector Machine)是机器学习中常见的一种分类算法. 线性分类器,也可以叫做感知机,其 ...

  4. Robo 3T SQL

    查询指定日期,指定显示字段,排序,注释功能 db.getCollection('spuBasisInfo') .find({"createTime":{$gte:ISODate(& ...

  5. android开机启动流程说明

    android开机启动流程说明 第一步:启动linux 1.Bootloader 2.Kernel 第二步android系统启动:入口为init.rc(system\core\rootdir) 1./ ...

  6. mysql(单表查询,多表查询,MySQl创建用户和授权,可视化工具Navicat的使用)

    单表查询 语法: 一.单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT ...

  7. 记录java+testng运行selenium(四)--- 运行代码

    涉及的文件有: .\medical\BusinessFile.java :实例化excel及xml文件操作对象以及将list变成Map .\medical\manual\business\LoginB ...

  8. SATB的标记问题解决之道与G1垃圾收集模式系统详解及最佳实践

    继续接着上一次https://www.cnblogs.com/webor2006/p/11148282.html的理论学习,上一次学习到了这: 接着继续: SATB详解: 对于三色算法在concurr ...

  9. springboot中用来进行查看错误日志的logback文件

    <?xml version="1.0" encoding="UTF-8"?> <!-- 从高到地低 OFF . FATAL . ERROR . ...

  10. 并发编程大师系列之:wait/notify/notifyAll/condition

    1. wait().notify()和notifyAll()方法是本地方法,并且为final方法,无法被重写. 2. 调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的mon ...