`

【Lucene3.0 初窥】索引文件格式(1):预备知识

阅读更多

注意,本专题内容参见《http://lucene.apache.org/java/3_0_1/fileformats.html

 

深入了解Lucene的磁盘索引文件,可以使我们对IR系统底层数据存储结构有一个深刻的认识。在《索引文件格式》这一专题中,我们将详细探讨 Lucene 3.0索引数据在磁盘上的存储格式,并通过一个实例进一步理解这些格式。但首先,我们必须准备点Lucene 索引文件格式的基础知识。

 

 

 

 

★ Lucene 自定义的基本数据类型

 

【Byte】  由8 bits组成的基本数据类型。所有其他的数据类型都是一个byte 串。因此,Lucene的索引文件都可以看成是有序的byte 串

【UInt32】 由4 byte 组成的32位无符号整 ,高位优先。UInt32 --> <Byte>4

【UInt64】 由8 byte 组成的64位无符号整型,高位优先。 UInt64 --> <Byte>8

【VInt】 可变长整型,为正整数定义的可变长格式。其特殊之处在于: 每字节的最高位表明后面还有一个字节,每字节的低七位表明整数的值,高位优先。因此 单个字节能表示的整数范围为0-127,而128到16383必须存储在两个字节中。比如下表:

  Value    

First byte 

Second byte

Third byte  

0

00000000

 

 

1

00000001

 

 

2

00000010

 

 

...

...

...

...

127

01111111

 

 

128

10000000

00000001

 

129

10000001

00000001

 

130

10000010

00000001

 

...

...

...

...

16,383

11111111

01111111

 

16,384

10000000

10000000

00000001

16,385

10000001

10000000

00000001

【Chars】 采用UTF-8编码的Unicode字符序列

【String】 由VInt 和 Chars组成的字符串类型,其中VInt表示了Chars的长度,Chars表示了String的值。比如:

字符串"name"在Lucene的存储结构中表示为:4,110,97,109,101。其中4为字符的长度,后面4bytes分别表示四个字 符。

 

 

 

 

 

 

 

★ 空间复杂度的优化 —— Lucene压缩技术

    信息检索领域中一个非常重要的研究课题就是如何将海量的信息存储起来。Lucene建立倒排索引结构,需要将词语、文档号、词频、位置信息写入磁盘文件。需要检索的文本越多,信息量就越大。因此Lucene使用了一些数据压缩技术来尽量减少数据存储所需要的空间。

 

(1) 前缀规则 Prefix

      所谓前缀规则,即当前词和前一个词有共同的前缀的时候,当前词仅仅保存前缀之后的子串。比如“term terminal”这两个词的存储如下所示, 注意:前缀规则只适用于两个相邻的词。

                                                 t e r m 4  i n a l

      我们来看看压缩的效率:假设有term,termagancy,termagant,termina四个词。每个字母需要1byte的空间。常规存储一共需要35byte。而压缩存储之后为:"term4agancy8t4inal"。一共需要22byte.

      Lucene倒排索引文件的Dictionary主要就采用了这种压缩技术。其效果非常理想,原因就在于Dictionary中的词语都按照字典序进行排序,两个相邻的词语之间的具有很长的相同前缀。

 

 

(2) 差值规则(Delta)

      所谓差值规则,就是两个连续存储的数据,后一个数据存储的是与前一个数据的差值。比如"1500000 1500001"这两个数据的存储如下所示, 注意:差值规则也必须在两个连续的存储数据之间发生。

                                                    1500000  1

      很显然,如果要存储一个比较大的数据,很有可能需要多个字节的存储空间。如果存储与前一个数据的差值,那么很有可能将数据控制在1byte之内。

      Lucene倒排索引文件中frequence、docID、position都采用了这种压缩技术。其原因就在于这三种信息具有一个相似的特性,就是信息的后一个数据基本上都是前一个数据增1。因此差值总是可以将很大的数用1来存储。

 

 

(3) 或然跟随规则

       或然跟随规则可以在某种特定的情况下将本需要2个空间存储的数据放在压缩成1个空间存储。 比如说某个数据A=1,其后紧跟的一个数据B=1。则可以采用(A<<1) | B 来存储,过程如下:

       A=00000001  B=00000001  --->   (A<<1) | B =00000010 | 00000001=00000011=3

       很显然,本需要2byte存储的A和B,现在只需要1byte就可以全部存储完毕了。

       但要注意,如果后面跟随的B>1怎么办?那么当然不可能将A的最后一个bit来存放B,只能放弃这种规则。但是如何区别使用或然规则压缩的数据和普通数据呢。只能将A进行左移1位而不与B或运算。

 

      Lucene中有很多情况符合这种具有一定条件约束的压缩技术。比如:.frq文件中的DocDelta[, Freq?]、prx文件中的PositionDelta,Payload?等。这些在后面的具体讨论中会详细讲到。

 

 

 

 

 

 

 

 

★ 时间复杂度的优化 —— Lucene 的跳表查询结构(Skip list)

 

    对于搜索引擎而言,查找时最主要的操作。为了提高查找的性能,Lucene在很多地方采取的跳跃表的数据结构。

 

    跳跃表(Skip List)是如图的一种数据结构,有以下几个基本特征:

  • 元素是按顺序排列的,在Lucene中,或是按字典顺序排列,或是按从小到大顺序排列。
  • 跳跃是有间隔的(Interval),也即每次跳跃的元素数,间隔是事先配置好的,如图跳跃表的间隔为3。
  • 跳跃表是由层次的(level),每一层的每隔指定间隔的元素构成上一层,如图跳跃表共有2层。

 

需要注意一点的是,在很多数据结构或算法书中都会有跳跃表的描述,原理都是大致相同的,但是定义稍有差别:

  • 对间隔(Interval)的定义: 如图中,有的认为间隔为2,即两个上层元素之间的元素数,不包括两个上层元素;有的认为是3,即两个上层元素之间的差,包括后面上层元素,不包括前面的上 层元素;有的认为是4,即除两个上层元素之间的元素外,既包括前面,也包括后面的上层元素。Lucene是采取的第二种定义。
  • 对层次(Level)的定义:如图中,有的认为应该包括原链表层,并从1开始计数,则总层次为3,为1,2,3层;有的认为应该包括原链表层,并 从0计数,为0,1,2层;有的认为不应该包括原链表层,且从1开始计数,则为1,2层;有的认为不应该包括链表层,且从0开始计数,则为0,1层。 Lucene采取的是最后一种定义。

跳跃表比顺序查找,大大提高了查找速度,如查找元素72,原来要访问2,3,7,12,23,37,39,44,50,72总共10个元素,应用跳 跃表后,只要首先访问第1层的50,发现72大于50,而第1层无下一个节点,然后访问第2层的94,发现94大于72,然后访问原链表的72,找到元 素,共需要访问3个元素即可。

8
0
分享到:
评论
1 楼 xchd 2013-10-23  
有代码例子吗

相关推荐

    lucene3.0 lucene3.0

    lucene3.0 lucene3.0 lucene3.0 lucene3.0 lucene3.0

    lucene3.0庖丁+索引搜索程序

    《深入剖析Lucene3.0:庖丁解牛与索引搜索实践》 在IT行业中,搜索引擎技术扮演着至关重要的角色,而Lucene作为一个开源全文检索库,为开发者提供了强大的文本搜索功能。本文将深入探讨Lucene3.0版本,结合“庖丁解...

    Lucene3.0创建索引

    ### Lucene3.0创建索引 在Lucene3.0中创建索引是一个关键功能,可以帮助用户快速地检索和管理大量的文本数据。本篇文章将详细介绍如何使用Lucene3.0来创建索引,并通过一个具体的例子来演示整个过程。 #### 一、...

    Lucene3.0之查询类型详解

    【Lucene3.0查询类型详解】 在Lucene3.0中,查询处理是一个关键环节,涉及多种查询方式和理论模型。以下是对这些概念的详细解释: 1. **查询方式**: - **顺序查询**:是最简单的查询方式,直接遍历索引,效率较...

    lucene 3.0 API 中文帮助文档 chm

    lucene 3.0 API中文帮助,学习的人懂得的

    Lucene 3.0 原理与代码分析完整版

    1. Directory:用于存储索引的文件系统抽象,如FSDirectory(文件系统目录)和RAMDirectory(内存目录)。 2. IndexWriter:负责创建和更新索引,支持批量添加、删除和更新文档。 3. IndexReader:读取索引,用于...

    lucene3.0核心jar包

    在 Lucene 3.0 中,索引过程包括分词、字段处理、文档ID分配等步骤,生成的索引文件包括词典、Posting List、Doc IDs 等组件。 2. **分词器(Analyzer)**:Lucene 提供了多种分词器,如 StandardAnalyzer、...

    lucene3.0资料包

    总结,Lucene3.0是全文检索领域的一个强大工具,其索引构建、分词、查询解析、搜索算法等功能在当时具有很高的技术水平,并且具有高度的灵活性和扩展性。通过深入学习和应用Lucene3.0,开发者可以构建出高效、智能的...

    Lucene3.0做的文件搜索

    在Lucene 3.0版本中,这个功能得到了进一步加强,支持了多种文件格式的搜索,使得用户可以对各种类型的文档进行快速而准确的检索。 **1. Lucene索引原理** Lucene的核心在于它的索引机制。索引过程主要包括文档...

    lucene3.0 实例

    生成索引的类通常会读取文件内容,创建 Lucene 文档,然后将这些文档添加到索引中。这个过程包括以下几个步骤: 1. 初始化索引目录:使用 `FSDirectory.open()` 创建指向索引存储位置的目录对象。 2. 创建索引...

    Lucene3.0全文信息检索

    1. **索引**:Lucene首先将文档内容转换成倒排索引(Inverted Index),这是一个数据结构,用于快速定位包含特定单词的文档。通过索引,Lucene能够高效地执行全文搜索。 2. **分词**(Tokenization):Lucene使用...

    lucene 2.0 api以及lucene 3.0 api

    1. **SegmentMerger 改进**: Lucene 3.0 中,`MergePolicy` 和 `MergeScheduler` 分离,提供更灵活的索引合并策略。 2. **N-gram 查询支持**: 新增了对 N-gram 查询的支持,增强了短语查询和部分匹配的能力。 3. *...

    lucene3.0 分词器

    lucene3.0 中文分词器, 庖丁解牛

    lucene3.0使用介绍及实例

    以下是一个简单的Lucene 3.0索引和搜索的Java示例: ```java import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document....

    Lucene 3.0 原理与代码分析PDF

    Lucene学习总结之三:Lucene的索引文件格式(1) Lucene学习总结之三:Lucene的索引文件格式(2) Lucene学习总结之三:Lucene的索引文件格式(3) Lucene学习总结之四:Lucene索引过程分析(1) Lucene学习总结之...

    Lucene 3.0完成入门

    本篇文章将围绕 Lucene 3.0 版本,详细介绍其入门知识,并通过提供的文档列表,帮助你深入了解并实现简单的搜索功能。 1. **Lucene 3.0 的基础概念** - **索引**:Lucene 的核心是索引,它是一种预处理步骤,将...

    lucene3.0英文API

    1. **改进的性能**:Lucene 3.0引入了更高效的内存管理,优化了索引和搜索速度。 2. **多线程支持**:增加了对并发写入和读取的支持,提升了多用户环境下的性能。 3. **新的分析器**:提供了更多针对特定语言的...

Global site tag (gtag.js) - Google Analytics