Lucene核心数据结构——FST存词典,跳表存倒排或者roarning bitmap 见另外一个文章
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 见另外一个文章的更多相关文章
- 聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)
redis使用跳表不用B+数的原因是:redis是内存数据库,而B+树纯粹是为了mysql这种IO数据库准备的.B+树的每个节点的数量都是一个mysql分区页的大小(阿里面试) 还有个几个姊妹篇:介绍 ...
- 自己动手实现java数据结构(九) 跳表
1. 跳表介绍 在之前关于数据结构的博客中已经介绍过两种最基础的数据结构:基于连续内存空间的向量(线性表)和基于链式节点结构的链表. 有序的向量可以通过二分查找以logn对数复杂度完成随机查找,但由于 ...
- lucene底层数据结构——FST,针对field使用列存储,delta encode压缩doc ids数组,LZ4压缩算法
参考: http://www.slideshare.net/lucenerevolution/what-is-inaluceneagrandfinal http://www.slideshare.ne ...
- lucene .doc里存储的skiplist跳表
http://forfuture1978.iteye.com/blog/546841 见图: lucene-6.5.1-src/lucene-6.5.1$ grep "skiplistwri ...
- ES索引文件和数据文件大小对比——splunk索引文件大小远小于ES,数据文件的压缩比也较ES更低,有趣的现象:ES数据文件zip压缩后大小和splunk的数据文件相当!词典文件tim/tip+倒排doc/pos和cfs文件是索引的大头
和splunk对比: ES中各个倒排索引文件的分布: 测试说明:ES2.41版本,数据使用500次批量插入,每批数据都不同,大小500条,每条数据50个字段,对应的字符串使用长度为1-10个单词随机生 ...
- skiplist(跳表)的原理及JAVA实现
前记 最近在看Redis,之间就尝试用sortedSet用在实现排行榜的项目,那么sortedSet底层是什么结构呢? "Redis sorted set的内部使用HashMap和跳跃表(S ...
- [转载] 跳表SkipList
原文: http://www.cnblogs.com/xuqiang/archive/2011/05/22/2053516.html leveldb中memtable的思想本质上是一个skiplist ...
- 跳表SkipList
原文:http://www.cnblogs.com/xuqiang/archive/2011/05/22/2053516.html 跳表SkipList 1.聊一聊跳表作者的其人其事 2. 言归正 ...
- C语言跳表(skiplist)实现
一.简介 跳表(skiplist)是一个非常优秀的数据结构,实现简单,插入.删除.查找的复杂度均为O(logN).LevelDB的核心数据结构是用跳表实现的,redis的sorted set数据结构也 ...
随机推荐
- 如何去把内容分享到whatsapp上?
使用场景,公司利用whatsapp来推广商品,需要把商品和一些基本信息分享到WhatsApp上; 一:在html的head标签里面通过meta标签加上一些分享的基本网站信息,具体代码如下 <me ...
- S3C2440 gpio + main
相关文章:http://blog.csdn.net/zhangxuechao_/article/details/77990854 举例 start.S .globl _start _start: /* ...
- SAP Marketing Cloud功能简述(三) 营销活动内容设计和产品推荐
Grace的前两篇文章: SAP Marketing Cloud功能简述(一) : Contacts和Profiles SAP Marketing Cloud功能简述(二) : Target Grou ...
- 【vue&ts开发】Vue 3.0前的 TypeScript 最佳入门实践
1.使用官方脚手架构建 新的 VueCLI工具允许开发者 使用 TypeScript 集成环境 创建新项目. 只需运行 vue createmy-app. 然后,命令行会要求选择预设.使用箭头键选择 ...
- 【Mybatis】 入门
一.概述 1.1 JDBC 1.2 JDBC编程中问题 1.3 MyBatis介绍 1.4 Mybatis架构 二.MyBatis入门程序 2.1 需求 2.2 引入MyBatis依赖 2.3 配置 ...
- 分组函数(groupby、itemgetter)
from itertools import groupby from operator import itemgetter d1={'name':'liuyi','age':25,'city':'SZ ...
- STM32定时器配置(TIM1、TIM2、TIM3、TIM4、TIM5、TIM8)高级定时器+普通定时器,定时计数模式下总结
文章结构: ——> 一.定时器基本介绍 ——> 二.普通定时器详细介绍TIM2-TIM5 ——> 三.定时器代码实例 一.定时器基本介绍 之前有用过野火的学习板上面讲解很详细,所以 ...
- STM32 HAL库学习系列第8篇---回调函数总结
普通函数与回调函数的区别:就是ST将中断封装,给使用者的API,就是标准库的中断函数 对普通函数的调用: 调用程序发出对普通函数的调用后,程序执行立即转向被调用函数执行,直到被调用函数执行完毕后,再返 ...
- 用js刷剑指offer(二叉搜索树与双向链表)
题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 牛客网链接 js代码 /* function TreeNode(x) { ...
- 3星|华杉华楠《超级符号原理》:超级符号是指注册为商标的企业logo
“ 超级符号是私有财产,超级符号是通过对传统符号的改造,使之成为注册商标,成为私有化财产,通过占有它,让竞争对手无法使用.P112” 超级符号原理 作者: 华杉 华楠 出版社: 文汇出版社 出版年: ...