lucene .doc文件格式解析——见图
摘自:http://forfuture1978.iteye.com/blog/546841
4.2.2. 文档号及词频(frq)信息

文档号及词频文件里面保存的是倒排表,是以跳跃表形式存在的。
- 此文件包含TermCount个项,每一个词都有一项,因为每一个词都有自己的倒排表。
- 对于每一个词的倒排表都包括两部分,一部分是倒排表本身,也即一个数组的文档号及词频,另一部分是跳跃表,为了更快的访问和定位倒排表中文档号及词频的位置。
- 对于文档号和词频的存储应用的是差值规则和或然跟随规则,Lucene的文档本身有以下几句话,比较难以理解,在此解释一下:
|
For example, the TermFreqs for a term which occurs once in document seven and three times in document eleven, with omitTf false, would be the following sequence of VInts: 15, 8, 3 If omitTf were true it would be this sequence of VInts instead: 7,4 首先我们看omitTf=false的情况,也即我们在索引中会存储一个文档中term出现的次数。 例子中说了,表示在文档7中出现1次,并且又在文档11中出现3次的文档用以下序列表示:15,8,3. 那这三个数字是怎么计算出来的呢? 首先,根据定义TermFreq --> DocDelta[, Freq?],一个TermFreq结构是由一个DocDelta后面或许跟着Freq组成,也即上面我们说的A+B?结构。 DocDelta自然是想存储包含此Term的文档的ID号了,Freq是在此文档中出现的次数。 所以根据例子,应该存储的完整信息为[DocID = 7, Freq = 1] [DocID = 11, Freq = 3](见全文检索的基本原理章节)。 然而为了节省空间,Lucene对编号此类的数据都是用差值来表示的,也即上面说的规则2,Delta规则,于是文档ID就不能按完整信息存了,就应该存放如下: [DocIDDelta = 7, Freq = 1][DocIDDelta = 4 (11-7), Freq = 3] 然而Lucene对于A+B?这种或然跟随的结果,有其特殊的存储方式,见规则3,即A+B?规则,如果DocDelta后面跟随的Freq为1,则用DocDelta最后一位置1表示。 如果DocDelta后面跟随的Freq大于1,则DocDelta得最后一位置0,然后后面跟随真正的值,从而对于第一个Term,由于Freq为1,于是放在DocDelta的最后一位表示,DocIDDelta = 7的二进制是000 0111,必须要左移一位,且最后一位置一,000 1111 = 15,对于第二个Term,由于Freq大于一,于是放在DocDelta的最后一位置零,DocIDDelta = 4的二进制是0000 0100,必须要左移一位,且最后一位置零,0000 1000 = 8,然后后面跟随真正的Freq = 3。 于是得到序列:[DocDleta = 15][DocDelta = 8, Freq = 3],也即序列,15,8,3。 如果omitTf=true,也即我们不在索引中存储一个文档中Term出现的次数,则只存DocID就可以了,因而不存在A+B?规则的应用。 [DocID = 7][DocID = 11],然后应用规则2,Delta规则,于是得到序列[DocDelta = 7][DocDelta = 4 (11 - 7)],也即序列,7,4. |
- 对于跳跃表的存储有以下几点需要解释一下:
- 跳跃表可根据倒排表本身的长度(DocFreq)和跳跃的幅度(SkipInterval)而分不同的层次,层次数为NumSkipLevels = Min(MaxSkipLevels, floor(log(DocFreq/log(SkipInterval)))).
- 第Level层的节点数为DocFreq/(SkipInterval^(Level + 1)),level从零计数。
- 除了最高层之外,其他层都有SkipLevelLength来表示此层的二进制长度(而非节点的个数),方便读取某一层的跳跃表到缓存里面。
- 低层在前,高层在后,当读完所有的低层后,剩下的就是最后一层,因而最后一层不需要SkipLevelLength。这也是为什么Lucene文档中的格式描述为 NumSkipLevels-1, SkipLevel,也即低NumSKipLevels-1层有SkipLevelLength,最后一层只有SkipLevel,没有SkipLevelLength。
- 除最低层以外,其他层都有SkipChildLevelPointer来指向下一层相应的节点。
- 每一个跳跃节点包含以下信息:文档号,payload的长度,文档号对应的倒排表中的节点在frq中的偏移量,文档号对应的倒排表中的节点在prx中的偏移量。
- 虽然Lucene的文档中有以下的描述,然而实验的结果却不是完全准确的:
|
Example: SkipInterval = 4, MaxSkipLevels = 2, DocFreq = 35. Then skip level 0 has 8 SkipData entries, containing the 3rd, 7th, 11th, 15th, 19th, 23rd, 27th, and 31st document numbers in TermFreqs. Skip level 1 has 2 SkipData entries, containing the 15th and 31st document numbers in TermFreqs. 按照描述,当SkipInterval为4,且有35篇文档的时候,Skip level = 0应该包括第3,第7,第11,第15,第19,第23,第27,第31篇文档,Skip level = 1应该包括第15,第31篇文档。 然而真正的实现中,跳跃表节点的时候,却向前偏移了,偏移的原因在于下面的代码:
从代码中,我们可以看出,当SkipInterval为4的时候,当docID = 0时,++df为1,1%4不为0,不是跳跃节点,当docID = 3时,++df=4,4%4为0,为跳跃节点,然而skipData里面保存的却是lastDocID为2。 所以真正的倒排表和跳跃表中保存一下的信息: |
lucene .doc文件格式解析——见图的更多相关文章
- ArcGIS三大文件格式解析
原文:ArcGIS三大文件格式解析 Shape数据 Shapefile是ArcView GIS 3.x的原生数据格式,属于简单要素类,用点.线.多边形存储要素的形状,却不能存储拓扑关系,具有简单.快速 ...
- Lucene 全文搜索解析
一.创建查询对象的方式 对要搜索的信息创建 Query 查询对象,Lucene 会根据 Query 查询对象生成最终的查询语法.类似关系数据库 Sql 语法一样,Lucene 也有自己的查询语法,比如 ...
- Android init.rc文件格式解析
/***************************************************************************** * Android init.rc文件格式 ...
- mp4文件格式解析(转载)
mp4文件格式解析 原作:http://blog.sina.com.cn/s/blog_48f93b530100jz4b.html 目前MP4的概念被炒得很火,也很乱.最开始MP4指的是音频(MP3的 ...
- C++PE文件格式解析类(轻松制作自己的PE文件解析器)
PE是Portable Executable File Format(可移植的运行体)简写,它是眼下Windows平台上的主流可运行文件格式. PE文件里包括的内容非常多,详细我就不在这解释了,有兴趣 ...
- 解析prototxt文件的python库 prototxt-parser(使用parsy自定义文件格式解析)
解析prototxt文件的python库 prototxt-parser https://github.com/yogin16/prototxt_parser https://test.pypi.or ...
- mp4文件格式解析(转)
mp4文件格式解析 MP4文件格式带数据详解 MP4文件格式的解析,以及MP4文件的分割算法
- Qt的.pro文件格式解析
Qt的.pro文件格式解析 在Qt中用qmake生成makefile文件,它是由.pro文件生成而来的,.pro文件的具体格式语法如下: 1.注释 .pro文件中注释采用#号,从"#&quo ...
- Lucene学习总结之七:Lucene搜索过程解析
一.Lucene搜索过程总论 搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程. 其可用如下图示: 总共包括以下几个过程: ...
随机推荐
- 在springBoot的控制台打印sql语句
在springBoot+Mybatis日志显示SQL的执行情况的最简单方法就是在properties新增: properties形式 logging.level.com.eth.wallet.mapp ...
- Python 字符编码-文件处理
.read #读取所有内容,光标移动到文件末尾.readable #判断文件是否可读.readline #读取一行内容,光标移动到第二行首部.readlines #读取每一行内容,存放于列表中.wri ...
- sort cmp函数的写法 (特判排序 二级排序)
特判排序: 看看以下cmp写法,猜想作用: 该函数作用就是“将正数升序排列, 负数排到最后” 我认为cmp函数的一个特性就是, 如果return false, 那么函数就会将他们互换位置, retur ...
- java读utf8 的txt文件,第一个字符为空或问号问题
参考:https://blog.csdn.net/yangzhichao888/article/details/79529756 https://blog.csdn.net/wangzhi291/ar ...
- 【BZOJ2440】完全平方数(莫比乌斯函数,容斥原理)
题意:求第k个无平方因子数 k<=10^9 思路: 感觉这东西和欧拉筛差不多……活到老学到老,退役前学点新知识也是好的 为什么二分答案的上界是2*n?连LYY都证不出来 话说约大爷一年之前就已经 ...
- LOJ#541. 「LibreOJ NOIP Round #1」七曜圣贤
有一辆车一开始装了编号0-a的奶茶,现有m次操作,每次操作Pi在[-1,b),若Pi为一个未出现过编号的奶茶,就把他买了并装上车:若Pi为一个在车上的奶茶,则把他丢下车:否则,此次操作为捡起最早丢下去 ...
- POJ 1182_食物链
题意: 三种动物A,B,C,A吃B,B吃C,C吃A, 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类. 第二种说法是" ...
- [bzoj3252]攻略_dfs序_线段树_贪心
攻略 bzoj-3252 题目大意:给定一棵n个节点的有根树,点有点权.让你选出至多k个节点,使得他们到根的链的并最大. 注释:$1\le n\le 2\cdot 10^5$,$1\le val_i\ ...
- HDU——1179 Ollivanders: Makers of Fine Wands since 382 BC.
Ollivanders: Makers of Fine Wands since 382 BC. Time Limit: 2000/1000 MS (Java/Others) Memory Lim ...
- Google Kaptcha验证码的使用
原文:http://www.kailing.pub/article/index/arcid/92.html Kaptcha是什么? kaptcha 是谷歌开源的非常实用的验证码生成工具,基于Simpl ...
