转自: http://www.cnblogs.com/forfuture1978/p/3945755.html 好好看看吧 倒排列表信息中词典相关存储的最关键格式 占倒排列表中文件大小的多数

我们来看最复杂的部分,就是Term Dictionary和Term Index文件,Term Dictionary文件的后缀名为tim,Term Index文件的后缀名是tip,格式如图所示。

Term Dictionary文件首先是一个Header,接下来是PostingsHeader,这两个的格式一致,但是保存的是不同的信息。SkipInterval是跳跃表的跳的幅度,MaxSkipLevels是跳跃表的层数,SkipMinimun是应用跳跃表的最小倒排表长度,接下来就是Term的部分了。

在tim文件中,Term是分成Block进行保存的,如何将Term进行分块,则需要和tip文件配合。Term Index文件对于每一个Field都保存一个FSTIndex来帮助快速定位tim文件中属于这个Field的Term的位置,由于FSTIndex的长度不同,为了快速定位某个Field的位置,则应用指针列表规则,为每一个Field保存了指向这个Field的FSTIndex的指针。

这里比较令人困惑的一点就是,FST是什么,如何利用他来分块呢?

FST全程是Finite State Transducers,是一个带输出的有限状态机,看过前面有限状态机规则的可以知道,有限状态机逻辑上来讲就是一颗树,就像图3-71中的那棵树,从初始状态输入字符a到达状态a,输入字符b到达状态b,输入字符d到达状态d,不同的是状态d有输出,所谓的输出就是一个指针,指向tim文件中的位置。

Tim文件中Term的分块就是按照FST来的,图3-71中,Block 0中的所有的Term都是以abd为前缀的,Block 1中所有的Term都是以abe为前缀的。每一个Block都有一个Block Header,里面指明这个Block包含几个Term,假设个数为N,Suffix里面包含了N个后缀,比如Block 0中包含Term “abdi”和”abdj”,则这里面保存”i”和”j”。Stats里面包含了N个统计信息,每个统计信息包含docFreq和totalTermFreq。Metadata里面包含了指向倒排表文件frq和prx文件的指针。

下面咱们具体讨论,Term如何分块,Block如何写入,FSTIndex如何构造。

我们首先通过一个简单的例子,来看一下一个普通的FST是如何构造的,Lucene的文档里面给了类似下面这样一个例子。

这里InputValues是构造FST的输入,是根据这些字符串,构造出图3-71中的那棵树。

OutputValue是有限状态机的输出,由于在实际应用中,输出是一个指向tim文件的一个指针,一般是byte[]类型,所以我们也在这里弄了三个byte[]作为输出。

Builder就是有限状态机的构造器,它支持多种输出类型,我们这里用byte[]作为输出,所以输出类型我们选择BytesRef,这是对byte[]的一个封装。

下一步就是用Builder的add函数将输入和输出关联起来,由于builder的输入必须是IntsRef类型,所以需要从字符串转换成为IntsRef类型,输出也要将byte[]封装为BytesRef。

Builder的finish函数真正构造一个FST,在内存中形成一个二进制结构,通过它可以通过输入,快速查询输出,例如程序中的给出输入”acf”就能得到输出[5 6]。

从表面现象来看,我们甚至可以决定FST就是一个hash map,给出输入,得到输出。这就满足了作为Term Dictionary的要求,给出一个字符串,我马上能找到倒排表的位置。

下面是FST的序列化:关心底层存储可以了解下。

依次类推,当添加acf之后,frontier变成如下的数据结构。

形成的二进制数组如图3-75所示,由于有内容翻转,所以解析的时候需要从右向左解析。

默认情况下,BlockTreeTermsWriter有两个静态变量,DEFAULT_MIN_BLOCK_SIZE=25,DEFAULT_MAX_BLOCK_SIZE=48,MIN的意思是当某个状态节点的子节点个数超过25个的时候,可以写成一个Block,MAX的意思是当个数超过48的时候,则写成多个Block,多个Block构成一个层级Block。为了能够清晰的解析代码,我们设DEFAULT_MIN_BLOCK_SIZE=2,DEFAULT_MAX_BLOCK_SIZE=4。我们仅仅添加一篇文档,里面的Term依次为 abc abdf abdg abdh abei abej abek abel abem aben。所形成的状态树如图所示,根据MIN和MAX的设置,f, g, h会写成一个Block,i, j, k, l, m, n写成一个层级Block,c, d, e写成一个Block。

最终,tip和tim文件中Block和FSTIndex的格式和关系如图3-83所示。

最后我们再看一下FSTIndex的二进制内容,如下图3-84所示。

Lucene 4.X 倒排索引原理与实现: (3) Term Dictionary和Index文件 (FST详细解析)——直接看例子就明白了!!!的更多相关文章

  1. Lucene 4.X 倒排索引原理与实现: (3) Term Dictionary和Index文件 (FST详细解析)

    我们来看最复杂的部分,就是Term Dictionary和Term Index文件,Term Dictionary文件的后缀名为tim,Term Index文件的后缀名是tip,格式如图所示. Ter ...

  2. Lucene 4.X 倒排索引原理与实现: (1) 词典的设计

    词典的格式设计 词典中所保存的信息主要是三部分: Term字符串 Term的统计信息,比如文档频率(Document Frequency) 倒排表的位置信息 其中Term字符串如何保存是一个很大的问题 ...

  3. Lucene 4.X 倒排索引原理与实现: (2) 倒排表的格式设计

    1. 定长编码 最容易想到的方式就是常用的普通二进制编码,每个数值占用的长度相同,都占用最大的数值所占用的位数,如图所示. 这里有一个文档ID列表,254,507,756,1007,如果按照二进制定长 ...

  4. Lucene底层原理和优化经验分享(1)-Lucene简介和索引原理

    Lucene底层原理和优化经验分享(1)-Lucene简介和索引原理 2017年01月04日 08:52:12 阅读数:18366 基于Lucene检索引擎我们开发了自己的全文检索系统,承担起后台PB ...

  5. 深度解析 Lucene 轻量级全文索引实现原理

    一.Lucene简介 1.1 Lucene是什么? Lucene是Apache基金会jakarta项目组的一个子项目: Lucene是一个开放源码的全文检索引擎工具包,提供了完整的查询引擎和索引引擎, ...

  6. Lucene 的索引文件锁原理

    Lucene 的索引文件锁原理 2016/11/24 · IT技术 · lucene   环境 Lucene 6.0.0Java “1.8.0_111”OS Windows 7 Ultimate 线程 ...

  7. es倒排索引原理解析

    倒排索引原理 普通的存储方式是给每个文档编一个序号 然后让这个序号对应单个文档的所有内容  如果用这样的方式查找   当需要查找某个单词的时候需要遍历所有的文档集合 查找文档的效率会非常的慢 2.基本 ...

  8. C++多态的实现及原理详细解析

    C++多态的实现及原理详细解析 作者: 字体:[增加 减小] 类型:转载   C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型 ...

  9. 《Java虚拟机原理图解》 1.2.2、Class文件里的常量池具体解释(上)

    [last updated:2014/11/27] NO1.常量池在class文件的什么位置? 我的上一篇文章<Java虚拟机原理图解> 1.class文件基本组织结构中已经提到了clas ...

随机推荐

  1. 查看linux ubuntu版本

    ubuntu版本: lsb_release -a  linux版本: uname -a proc目录下记录的当前系统运行的各种数据,version记录的版本信息直接可以通过cat查看到. 使用命令:c ...

  2. python010 Python3 元组

    Python3 元组Python 的元组与列表类似,不同之处在于元组的元素不能修改.元组使用小括号,列表使用方括号.元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可.如下实例: tup1 = ...

  3. iRule Event Order - HTTPv12

  4. POJ 1523 网络连通

    题目大意: 给你一个网络组,每台机子与其他机子的关系,让你找到所有的割点,如果没有割点,输出无 这道题目就是最直接的求割点问题,我在这里用的是邻接矩阵来存储机子之间的关系 割点问题的求解需要对深度优先 ...

  5. D 题

    题目大意:找朋友,最好把朋友最多的一堆的人数输出 运用并查集,每次更新最大数即可: 代码: #include <iostream> #include <cstdio> #inc ...

  6. [luoguP1168]中位数(主席树+离散化)

    传送门 模板题一道,1A. ——代码 #include <cstdio> #include <algorithm> #define ls son[now][0], l, mid ...

  7. hdu 2126背包问题

    /*有n件物品,旅客一共有m块大洋.第一个问题,旅客最多可以买多少件物品?请注意,这里是多少件,不是价值最大.所以这个非常好求,将所有的物品按照价值排序,先买便宜的,再买贵的.贪心的思想.这个地方有些 ...

  8. 导师高茂源:用CODEX创新方法破解西方创新“秘密”(转)

    高茂源,“CODEX创新体系”的创立者,精一学社的创业导师.“CODEX”是Copy.Optimize.Dimension.Ecosystem.Extra五个单词的缩写,该体系精炼了现在世界上流行的创 ...

  9. Codechef-BLACKCOM(树形背包dp)

    题意: 给你一棵由 N 个节点构成的树 T.节点按照 1 到 N 编号,每个节点要么是白色,要么是黑色.有 Q 组询问,每组询问形如 (s, b).你需要检查是否存在一个连通子图,其大小恰好是 s,并 ...

  10. 【stl学习笔记】红黑树

    转自维基百科 红黑树是一种平衡二叉搜索树,它可以在O(log n)时间内做查找,插入和删除,这里的n是树中元素的数目. 性质: 红黑树是每个节点都带有颜色属性的二叉查找树,颜色为红色或黑色.在二叉查找 ...