Lucene核心数据结构——FST存词典,跳表存倒排或者roarning bitmap 见另外一个文章
2017-02-13 16:43
441 查看
Lucene实现倒排表没有使用bitmap,为了效率,lucene使用了一些策略,具体如下:
1. 使用FST保存词典,FST可以实现快速的Seek,这种结构在当查询可以表达成自动机时(PrefixQuery、FuzzyQuery、RegexpQuery等)效率很高。(可以理解成自动机取交集)
此种场景主要用在对Query进行rewrite的时候。
2. FST可以表达出Term倒排表所在的文件偏移。
3. 倒排表使用SkipList结构。从上面的讨论可知,求倒排表的交集、并集、差集需要各种SeekTo(docId),SkipList能对Seek进行加速。
查询的过程很简单,从顶层开始,往后查询遇到节点的next()比待查的大或者到NIL了,节点不变下移一层继续向后查询,如此反复,直到到了底层还没查到。skiplist的资料也比较多,这里就不赘述了。
首先把倒排链按第一个next排序:
查看0~7的倒排链的第一个和最后一个是否相同,不同就开始找;取最后一个倒排的第一个元素8作为终点, 第一个链表开始找8
第0个链表 跳过1到了10,那么8也不用找了都去找10就行了
第1根链表找到了11,那么10也不用找了,找11,之后都这么做
......
之后遇到11,本次交集操作找到一个11,
后续的计算也是同理,当然整个代码实现会比较复杂和讨巧。基本思路就是每条倒排链能根据当前文档迅速跳过不符合的docid,由于倒排链可以用skiplist查询,因此即使很长的倒排链,如果交集的数量很少,整个求解过程可以很快跳过不需要比较的节点。
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查询,因此即使很长的倒排链,如果交集的数量很少,整个求解过程可以很快跳过不需要比较的节点。
相关文章推荐
- 使用LinkedList模拟一个堆栈或者队列数据结构
- Java使用LinkedList模拟一个堆栈或者队列数据结构
- 剽窃核心编程 共享区段共享数据 另外还有一个不太明白的 RegisterWindowMessage
- 使用LinkedList来模拟一个堆栈或者队列数据结构
- 数据库中快速备份一个表的数据,或者只备份表结构
- 使用LinkedList模拟一个堆栈或者队列数据结构
- 集合框架---使用LinkedList模拟一个堆栈或者队列数据结构
- 如何从一个表的数据更新到另外一个表的列或者插入
- 打开一个很好的介绍Lucene4 FST文章
- 如何将数据从一个form添加到另外一个form
- MySql的sql语句中添加存储过程或者存储函数来实现Oracle中的start with ……connect by prior……递归(树形结构数据)查询
- 解读Redis dict核心数据结构
- 数据结构与算法_两个栈实现一个队列的功能
- javasript dom 中获取元素类名 或者 改变类 引用另外一个类
- elasticsearch核心知识--37.搜索引擎_mapping复杂数据类型以及object类型数据底层结构
- 用lucene实现在一个(或者多个)字段中查找多个关键字
- 合并一个表格多个竖列的td,主要在后台改数据结构
- 在Excel表格中,通过公式查询数据并在另外一个文档中保存
- pandas核心数据结构series详解
- 如何将不同信息的数据对象合并显示到同一个页面上或者滚动窗口中