ImageVerifierCode 换一换
格式:DOC , 页数:41 ,大小:205.50KB ,
资源ID:8114770      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/8114770.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(开放源代码的全文检索引擎 Lucene.doc)为本站上传会员【pc****0】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

开放源代码的全文检索引擎 Lucene.doc

1、开放源代码的全文检索引擎 Lucene ――介绍、系统结构与源码实现分析   第一节 全文检索系统与Lucene简介   一、             什么是全文检索与全文检索系统?   全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。   全文检索的方法主要分为按字检索和按词检索两种。按字检索是指对于文章中的每一个字都建立索引,检索时将词分解为字的组合。对于各种不同的语言而言,字有

2、不同的含义,比如英文中字与词实际上是合一的,而中文中字与词有很大分别。按词检索指对文章中的词,即语义单位建立索引,检索时按词检索,并且可以处理同义项等。英文等西方文字由于按照空白切分词,因此实现上与按字处理类似,添加同义处理也很容易。中文等东方文字则需要切分字词,以达到按词索引的目的,关于这方面的问题,是当前全文检索技术尤其是中文全文检索技术中的难点,在此不做详述。   全文检索系统是按照全文检索理论建立起来的用于提供全文检索服务的软件系统。一般来说,全文检索需要具备建立索引和提供查询的基本功能,此外现代的全文检索系统还需要具有方便的用户接口、面向WWW[1]的开发接口、二次应用开发接口等

3、等。功能上,全文检索系统核心具有建立索引、处理查询返回结果集、增加索引、优化索引结构等等功能,外围则由各种不同应用具有的功能组成。结构上,全文检索系统核心具有索引引擎、查询引擎、文本分析引擎、对外接口等等,加上各种外围应用系统等等共同构成了全文检索系统。图1.1展示了上述全文检索系统的结构与功能。   在上图中,我们看到:全文检索系统中最为关键的部分是全文检索引擎,各种应用程序都需要建立在这个引擎之上。一个全文检索应用的优异程度,根本上由全文检索引擎来决定。因此提升全文检索引擎的效率即是我们提升全文检索应用的根本。另一个方面,一个优异的全文检索引擎,在做到效率优化的同时,还需要具有开放

4、的体系结构,以方便程序员对整个系统进行优化改造,或者是添加原有系统没有的功能。比如在当今多语言处理的环境下,有时需要给全文检索系统添加处理某种语言或者文本格式的功能,比如在英文系统中添加中文处理功能,在纯文本系统中添加XML[2]或者HTML[3]格式的文本处理功能,系统的开放性和扩充性就十分的重要。   二、             什么是Lucene?   Lucene是apache软件基金会[4] jakarta项目组的一个子项目,是一个开放源代码[5]的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引

5、擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。   Lucene的原作者是Doug Cutting,他是一位资深全文索引/检索专家,曾经是V-Twin搜索引擎[6]的主要开发者,后在Excite[7]担任高级系统架构设计师,目前从事于一些Internet底层架构的研究。早先发布在作者自己的   三、             Lucene的应用、特点及优势   作为一个开放源代码项目,Lucene从问世之后,引发了开放源代码社群的巨大反响,程序员们不仅使用它构

6、建具体的全文检索应用,而且将之集成到各种系统软件中去,以及构建Web应用,甚至某些商业软件也采用了Lucene作为其内部全文检索子系统的核心。apache软件基金会的网站使用了Lucene作为全文检索的引擎,IBM的开源软件eclipse[9]的2.1版本中也采用了Lucene作为帮助子系统的全文索引引擎,相应的IBM的商业软件Web Sphere[10]中也采用了Lucene。Lucene以其开放源代码的特性、优异的索引结构、良好的系统架构获得了越来越多的应用。   Lucene作为一个全文检索引擎,其具有如下突出的优点: (1)索引文件格式独立于应用平台。Lucene定义了一套以8位

7、字节为基础的索引文件格式,使得兼容系统或者不同平台的应用能够共享建立的索引文件。 (2)在传统全文检索引擎的倒排索引的基础上,实现了分块索引,能够针对新的文件建立小文件索引,提升索引速度。然后通过与原有索引的合并,达到优化的目的。 (3)优秀的面向对象的系统架构,使得对于Lucene扩展的学习难度降低,方便扩充新功能。 (4)设计了独立于语言和文件格式的文本分析接口,索引器通过接受Token流完成索引文件的创立,用户扩展新的语言和文件格式,只需要实现文本分析的接口。 (5)已经默认实现了一套强大的查询引擎,用户无需自己编写代码即使系统可获得强大的查询能力,Lucene的查询实现中默认实

8、现了布尔操作、模糊查询(Fuzzy Search[11])、分组查询等等。       面对已经存在的商业全文检索引擎,Lucene也具有相当的优势。首先,它的开发源代码发行方式(遵守Apache Software License[12]),在此基础上程序员不仅仅可以充分的利用Lucene所提供的强大功能,而且可以深入细致的学习到全文检索引擎制作技术和面相对象编程的实践,进而在此基础上根据应用的实际情况编写出更好的更适合当前应用的全文检索引擎。在这一点上,商业软件的灵活性远远不及Lucene。其次,Lucene秉承了开放源代码一贯的架构优良的优势,设计了一个合理而极具扩充能力的面向对象架构

9、程序员可以在Lucene的基础上扩充各种功能,比如扩充中文处理能力,从文本扩充到HTML、PDF[13]等等文本格式的处理,编写这些扩展的功能不仅仅不复杂,而且由于Lucene恰当合理的对系统设备做了程序上的抽象,扩展的功能也能轻易的达到跨平台的能力。最后,转移到apache软件基金会后,借助于apache软件基金会的网络平台,程序员可以方便的和开发者、其它程序员交流,促成资源的共享,甚至直接获得已经编写完备的扩充功能。最后,虽然Lucene使用Java语言写成,但是开放源代码社区的程序员正在不懈的将之使用各种传统语言实现(例如.net framework[14]),在遵守Lucene索引文

10、件格式的基础上,使得Lucene能够运行在各种各样的平台上,系统管理员可以根据当前的平台适合的语言来合理的选择。   四、             本文的重点问题与cLucene项目   作为中国人民大学信息学院99级本科生的一个毕业设计项目,我们对Lucene进行了深入的研究,包括系统的结构,索引文件结构,各个部分的实现等等。并且我们启动了cLucene项目,做为一个Lucene的C++语言的重新实现,以期望带来更快的速度和更加广泛的应用范围。我们先分析了系统结构,文件结构,然后在研究各个部分的具体实现的同时开始进行的cLucene实现。限于时间的限制,到本文完成为止,cLucene

11、项目并没有完成,对于Lucene的具体实现部分也仅仅完成到了索引引擎部分。   接下来的部分,本文将对Lucene的系统结构、文件结构、索引引擎部分做一个彻底的分析。以期望提供对Lucene全文检索引擎的系统架构和部分程序实现的清晰的了解。cLucene项目则作为一个开放源代码的项目,继续进行的开发。          有关cLucene项目的一些信息: n         开发语言:ISO C++[15],STLport 4.5.3[16],OpenTop 1.1[17] n         目标平台:Win32,POSIX n         授权协议:GNU General

12、 Public License (GPL)[18]     第二节 Lucene系统结构分析   一、             系统结构组织   Lucene作为一个优秀的全文检索引擎,其系统结构具有强烈的面向对象特征。首先是定义了一个与平台无关的索引文件格式,其次通过抽象将系统的核心组成部分设计为抽象类,具体的平台实现部分设计为抽象类的实现,此外与具体平台相关的部分比如文件存储也封装为类,经过层层的面向对象式的处理,最终达成了一个低耦合高效率,容易二次开发的检索引擎系统。   以下将讨论Lucene系统的结构组织,并给出系统结构与源码组织图:       从图中我们

13、清楚的看到,Lucene的系统由基础结构封装、索引核心、对外接口三大部分组成。其中直接操作索引文件的索引核心又是系统的重点。Lucene的将所有源码分为了7个模块(在java语言中以包即package来表示),各个模块所属的系统部分也如上图所示。需要说明的是org.apache.lucene.queryPaser是做为org.apache.lucene.search的语法解析器存在,不被系统之外实际调用,因此这里没有当作对外接口看待,而是将之独立出来。       从面象对象的观点来考察,Lucene应用了最基本的一条程序设计准则:引入额外的抽象层以降低耦合性。首先,引入对索引文件的操作o

14、rg.apache.lucene.store的封装,然后将索引部分的实现建立在(org.apache.lucene.index)其之上,完成对索引核心的抽象。在索引核心的基础上开始设计对外的接口org.apache.lucene.search与org.apache.lucene.analysis。在每一个局部细节上,比如某些常用的数据结构与算法上,Lucene也充分的应用了这一条准则。在高度的面向对象理论的支撑下,使得Lucene的实现容易理解,易于扩展。       Lucene在系统结构上的另一个特点表现为其引入了传统的客户端服务器结构以外的的应用结构。Lucene可以作为一个运行库被

15、包含进入应用本身中去,而不是做为一个单独的索引服务器存在。这自然和Lucene开放源代码的特征分不开,但是也体现了Lucene在编写上的本来意图:提供一个全文索引引擎的架构,而不是实现。 [B][/B]  二、             数据流分析   理解Lucene系统结构的另一个方式是去探讨其中数据流的走向,并以此摸清楚Lucene系统内部的调用时序。在此基础上,我们能够更加深入的理解Lucene的系统结构组织,以方便以后在Lucene系统上的开发工作。这部分的分析,是深入Lucene系统的钥匙,也是进行重写的基础。      我们来看看在Lucene系统中的主要的数据流以及它

16、们之间的关系图: 索引查找逻辑      索引构建逻辑      查询语句语法分析逻辑      词法分析逻辑       存储抽象            图2.2很好的表明了Lucene在内部的数据流组织情况,并且沿着数据流的方向我们也可以对与Lucene内部的执行时序有一个清楚的了解。现在将图中的涉及到的流的类型与各个逻辑对应系统的相关部分的关系说明一下。       图中共存在4种数据流,分别是文本流、token流、字节流与查询语句对象流。文本流表示了对于索引目标和交互控制的抽象,即用文本流表示了将要索引的文件,用文本流向用户输出信息;在实际的实

17、现中,Lucene中的文本流采用了UCS-2[19]作为编码,以达到适应多种语言文字的处理的目的。Token流是Lucene内部所使用的概念,是对传统文字中的词的概念的抽象,也是Lucene在建立索引时直接处理的最小单位;简单的讲Token就是一个词和所在域值的组合,后面在叙述文件格式时也将继续涉及到token,这里不详细展开。字节流则是对文件抽象的直接操作的体现,通过固定长度的字节(Lucene定义为8比特位长,后面文件格式将详细叙述)流的处理,将文件操作解脱出来,也做到了与平台文件系统的无关性。查询语句对象流则是仅仅在查询语句解析时用到的概念,它对查询语句抽象,通过类的继承结构反映查询语句

18、的结构,将之传送到查找逻辑来进行查找的操作。       图中的涉及到了多种逻辑,基本上直接对应于系统某一模块,但是也有跨模块调用的问题发生,这是因为Lucene的重用程度非常好,因此很多实现直接调用了以前的工作成果,这在某种程度上其实是加强了模块耦合性,但是也是为了避免系统的过于庞大和不必要的重复设计的一种折衷体现。词法分析逻辑对应于org.apache.lucene.analysis部分。查询语句语法分析逻辑对应于org.apache.lucene.queryParser部分,并且调用了org.apache.lucene.analysis的代码。查询结束之后向评分排序逻辑输出token

19、流,继而由评分排序逻辑处理之后给出文本流的结果,这一部分的实现也包含在了org.apache.lucene.search中。索引构建逻辑对应于org.apache.lucene.index部分。索引查找逻辑则主要是org.apache.lucene.search,但是也大量的使用了org.apache.lucene.index部分的代码和接口定义。存储抽象对应于org.apache.lucene.store。没有提到的模块则是做为系统公共基础设施存在。   三、             基于Lucene的应用开发   通过以上的系统结构分析和数据流分析,我们已经很清楚的了解了Lucen

20、e的系统的结构特征。在此基础上,我们可以通过扩充Lucene系统来完成一个完备的全文检索引擎,紧接着还可以在全文检索引擎的基础上构建各种应用系统。鉴于本文的目的并不在此,以下我们只是略为叙述一下相关的步骤,从而给出应用开发的一些思路。   首先,我们需要的是按照目标语言的词法结构来构建相应的词法分析逻辑,实现Lucene在org.apache.lucene.analysis中定义的接口,为Lucene提供目标系统所使用的语言处理能力。Lucene默认的已经实现了英文和德文的简单词法分析逻辑(按照空格分词,并去除常用的语法词,如英语中的is,am,are等等)。在这里,主要需要参考实现的接口

21、在org.apache.lucene.analysis中的Analyzer.java和Tokenizer.java中定义,Lucene提供了很多英文规范的实现样本,也可以做为实现时候的参考资料。其次,需要按照被索引的文件的格式来提供相应的文本分析逻辑,这里是指除开词法分析之外的部分,比如HTML文件,通常需要把其中的内容按照所属于域分门别类加入索引,这就需要从org.apache.lucene.document中定义的类document继承,定义自己的HTMLDocument类,然后就可以将之交给org.apache.lucene.index模块来写入索引文件。完成了这两步之后,Lucene全

22、文检索引擎就基本上完备了。这个过程可以用下图表示:       当然,上面所示的仅仅只是对于Lucene的基本扩充过程,它将Lucene由不完备的变成完备的(尤其是对于非英语的语言检索)。除此之外我们还可以在很多方面对Lucene进行改造。第一个方面即为按照文档索引的域,比如标题,作者之类的信息对返回的查询结果排序,这即需要改造Lucene的评分排序逻辑。默认的,Lucene采用其内部的相关性方法来处理评分和排序,我们可以根据需要改变它。遗憾的是,这部分Lucene并没有做到如同扩充词法解析和文档类型那样的条理清晰,没有留下很好的接口,因此需要仔细的分析其源代码的实现,自行扩充等等。其

23、他的方面,比如改进其索引的效率,改进其返回结果时候的缓冲机制等等,都是加强Lucene系统的方面,在此也不再叙述。       完成了Lucene系统,之后就可以开始考虑其上的应用系统开发。如果应用系统也使用java语言开发,那么Lucene系统能够方便的嵌入到整个系统中去,作为一个API集来调用。这个过程十分简单,以下便是一个示例程序,配合注释理解起来很容易。 图 2.4 Lucene应用代码示例            或者,Lucene全文检索引擎也可作为服务器程序启动,但是这就需要用户自行扩充其他应用与Lucene的接口。这个可以通过传统的包装方式,比如客户服务器结构,

24、或者采用现在流行的Web方式。诸如此类的应用方案,本文也不再继续叙述。参考Lucene的项目网站中的用户邮件列表能找到更多的信息。     第三节 Lucene索引文件格式分析   一、             Lucene源码实现分析的说明   通过以上对Lucene系统结构的分析,我们已经大致的清楚了Lucene系统的组成,以及在Lucene系统之上的开发步骤。接下来,我们试图来分析Lucene项目(采用Lucene 1.2版本)的源码实现,考察其实现的细节。这不仅仅是我们尝试用C++语言重新实现Lucene的必须工作,也是进一步做Lucene开发工作的必要准备。因此,这一部

25、分所涉及到的内容,对于Lucene上的应用开发也是有价值的,尤其是本部分所做的文件格式分析。       由于本文建立在我们的毕设项目之上,且同时我们需要实现cLucene项目,因此很遗憾的我们并没有完全的完成Lucene的所有源码实现的分析工作。接下来的部分,我们将涉及的部分为Lucene文件格式分析,Lucene中的存储抽象模块分析,以及Lucene中的索引构建逻辑模块分析。这一部分,我们主要涉及到的是文件格式分析与存储抽象模块分析。   二、             Lucene索引文件格式   在Lucene的web站点上,有关于Lucene的文件格式的规范,其规定了Luc

26、ene的文件格式采取的存储单位、组织结构、命名规范等等内容,但是它仅仅是一个规范说明,并没有从实现者角度来衡量这个规范的实现。因此,我们以下的内容,结合了我们自己的分析与文件格式的定义规范,以期望给出一个更加清晰的文件格式说明。具体的文档规范可以参考后面的文献2。       首先在Lucene的文件格式中,以字节为基础,定义了如下的数据类型:   表 3.1 Lucene文件格式中定义的数据类型 数据类型  所占字节长度(字节)  说明   Byte  1  基本数据类型,其他数据类型以此为基础定义   UInt32  4  32位无符号整数,高位优先  

27、UInt64  8  64位无符号整数,高位优先   VInt  不定,最少1字节  动态长度整数,每字节的最高位表明还剩多少字节,每字节的低七位表明整数的值,高位优先。可以认为值可以为无限大。其示例如下 值  字节1  字节2  字节3   0  00000000         1  00000001         2  00000010         127  01111111         128  10000000  00000001      129  10000001  00000001   

28、   130  10000010  00000001      16383  10000000  10000000  00000001   16384  10000001  10000000  00000001   16385  10000010  10000000  00000001     Chars  不定,最少1字节  采用UTF-8编码[20]的Unicode字符序列   String  不定,最少2字节  由VInt和Chars组成的字符串类型,VInt表示Chars的长度,Chars则表示了String的值      

29、   以上的数据类型就是Lucene索引文件格式中用到的全部数据类型,由于它们都以字节为基础定义而来,因此保证了是平台无关,这也是Lucene索引文件格式平台无关的主要原因。接下来我们看看Lucene索引文件的概念组成和结构组成。     以上就是Lucene的索引文件的概念结构。Lucene索引index由若干段(segment)组成,每一段由若干的文档(document)组成,每一个文档由若干的域(field)组成,每一个域由若干的项(term)组成。项是最小的索引概念单位,它直接代表了一个字符串以及其在文件中的位置、出现次数等信息。域是一个关联的元组,由一个域名和一个域值组成,域名

30、是一个字串,域值是一个项,比如将“标题”和实际标题的项组成的域。文档是提取了某个文件中的所有信息之后的结果,这些组成了段,或者称为一个子索引。子索引可以组合为索引,也可以合并为一个新的包含了所有合并项内部元素的子索引。我们可以清楚的看出,Lucene的索引结构在概念上即为传统的倒排索引结构[21]。       从概念上映射到结构中,索引被处理为一个目录(文件夹),其中含有的所有文件即为其内容,这些文件按照所属的段不同分组存放,同组的文件拥有相同的文件名,不同的扩展名。此外还有三个文件,分别用来保存所有的段的记录、保存已删除文件的记录和控制读写的同步,它们分别是segments,delet

31、able和lock文件,都没有扩展名。每个段包含一组文件,它们的文件扩展名不同,但是文件名均为记录在文件segments中段的名字。让我们看如下的结构图3.2。 项集合信息       项位置       项频数      被删除文档       标准化因子       图 3.2 Lucene索引文件结构组成      segment1所含文件       项字典      域值存储表      域集合信息       index            关于图3.2中的各个文件具体的内部格式,在参考文献3中,均可以找到

32、详细的说明。接下来我们从宏观关系上说明一下这些文件组成。在这些宏观上的关系理清楚之后,仔细阅读参考文献3,即可清楚的明白具体的Lucene文件格式。       每个段的文件中,主要记录了两大类的信息:域集合与项集合。这两个集合中所含有的文件在图3.2中均有表明。由于索引信息是静态存储的,域集合与项集合中的文件组采用了一种类似的存储办法:一个小型的索引文件,运行时载入内存;一个对应于索引文件的实际信息文件,可以按照索引中指示的偏移量随机访问;索引文件与信息文件在记录的排列顺序上存在隐式的对应关系,即索引文件中按照“索引项1、索引项2…”排列,则信息文件则也按照“信息项1、信息项2…”排列。

33、比如在图3.2所示文件中,segment1.fdx与segment1.fdt之间,segment1.tii与segment1.tis、segment1.prx、segment1.frq之间,都存在这样的组织关系。而域集合与项集合之间则通过域的在域记录文件(比如segment1.fnm)中所记录的域记录号维持对应关系,在图3.2中segment1.fdx与segment1.tii中就是通过这种方式保持联系。这样,域集合和项集合不仅仅联系起来,而且其中的文件之间也相互联系起来。此外,标准化因子文件和被删除文档文件则提供了一些程序内部的辅助设施(标准化因子用在评分排序机制中,被删除文档是一种伪删除手

34、段)。这样,整个段的索引信息就通过这些文档有机的组成。       以上所阐述的,就是Lucene所采用的索引文件格式。基本上而言,它是一个倒排索引,但是Lucene在文件的安排上做了一些努力,比如使用索引/信息文件的方式,从文件安排的形式上提高查找的效率。这是一种数据库之外的处理方法,其有其优点(格式平台独立、速度快),也有其缺点(独立性带来的共享访问接口问题等等),具体如何衡量两种方法之间的利弊,本文这里就不讨论了。   三、             一些公用的基础类   分析完索引文件格式,我们接下来应该着手对存储抽象也就是org.apache.lucenestore中的源码

35、做一些分析。我们先不着急分析这部分,而是分析图2.1中基础结构封装那一部分,因为这是整个系统的基石,然后我们在下一部分再来分析存储抽象。       基础结构封装,或者基础类,由org.apache.lucene.util和org.apache.lucene.document两个包组成,前者定义了一些常量和优化过的常用的数据结构和算法,后者则是对于文档(document)和域(field)概念的一个类定义。以下我们用列表的方式来分析这些封装类,指出其要点。   表 3.2 基础类包org.apache.lucene.util 类  说明   Arrays  一个关于数组的排序

36、方法的静态类,提供了优化的基于快排序的排序方法sort   BitVector  C/C++语言中位域的java实现品,但是加入了序列化能力   Constants  常量静态类,定义了一些常量   PriorityQueue  一个优先队列的抽象类,用于后面实现各种具体的优先队列,提供常数时间内的最小元素访问能力,内部实现机制是哈析表和堆排序算法     表 3.3 基础类包org.apache.lucene.document 类  说明   Document  是文档概念的一个实现类,每个文档包含了一个域表(fieldList),并提供了一些实用的方法,比

37、如多种添加域的方法、返回域表的迭代器的方法   Field  是域概念的一个实现类,每个域包含了一个域名和一个值,以及一些相关的属性   DateField  提供了一些辅助方法的静态类,这些方法将java中Date和Time数据类型和String相互转化     总的来说,这两个基础类包中含有的类都比较简单,通过阅读源代码,可以很容易的理解,因此这里不作过多的展开。   四、             存储抽象   有了上面的知识,我们接下来来分析存储抽象部分,也就是org.apache.lucene.store包。存储抽象是唯一能够直接对索引文件存取的包,因此其主要

38、目的是抽象出和平台文件系统无关的存储抽象,提供诸如目录服务(增、删文件)、输入流和输出流。在分析其实现之前,首先我们看一下UML[22]图。 图 3.3 存储抽象实现UML图(一) 图 3.4 存储抽象实现UML图(二) 图 3.4 存储抽象实现UML图(三)       图3.2到3.4展示了整个org.apache.lucene.store中主要的继承体系。共有三个抽象类定义:Directory、InputStream和OutputStrem,构成了一个完整的基于抽象文件系统的存取体系结构,在此基础上,实作出了两个实现品:(FSDirectory,FSInputStr

39、eam,FSOutputStream)和(RAMDirectory,RAMInputStream和RAMOutputStream)。前者是以实际的文件系统做为基础实现的,后者则是建立在内存中的虚拟文件系统。前者主要用来永久的保存索引文件,后者的作用则在于索引操作时是在内存中建立小的索引,然后一次性的输出合并到文件中去,这一点我们在后面的索引逻辑部分能够看到。此外,还定以了org.apache.lucene.store.lock和org.apache.lucene.store.with两个辅助内部实现的类用在实现Directory方法的makeLock的时候,以在锁定索引读写之前来让客户程序做一

40、些准备工作。       (FSDirectory,FSInputStream,FSOutputStream)的内部实现依托于java语言中的io类库,只是简单的做了一个外部逻辑的包装。这当然要归功于java语言所提供的跨平台特性,同时也带了一些隐患:文件存取的效率提升需要依耐于文件类库的优化。如果需要继续优化文件存取的效率,应该还提供一个文件与目录的抽象,以根据各种文件系统或者文件类型来提供一个优化的机会。当然,这是应用开发者所不需要关系的问题。       (RAMDirectory,RAMInputStream和RAMOutputStream)的内部实现就比较直接了,直接采用了虚

41、拟的文件RAMFile类(定义于文件RAMDirectory.java中)来表示文件,目录则看作一个String与RAMFile对应的关联数组。RAMFile中采用数组来表示文件的存储空间。在此的基础上,完成各项操作的实现,就形成了基于内存的虚拟文件系统。因为在实际使用时,并不会牵涉到很大字节数量的文件,因此这种设计是简单直接的,也是高效率的。       这部分的实现在理清楚继承体系后,相当的简单。因此接下来的部分,我们可以通过直接阅读源代码解决。接下来我们看看这个部分的源代码如何在实际中使用的。       一般来说,我们使用的是抽象类提供的接口而不是实际的实现类本身。在实现类中一

42、般都含有几个静态函数,比如createFile,它能够返回一个OutputStream接口,或者openFile,它能够返回一个InputStream接口,利用这些接口之中的方法,比如writeString,writeByte等等,我们就能够在抽象的层次上处理Lucene定义的数据类型的读写。简单的说,Lucene中存储抽象这部分设计时采用了工厂模式(Factory parttern)[23]。我们利用静态类的方法也就是工厂来创建对象,返回接口,通过接口来执行操作。   五、             关于cLucene项目   这一部分详细的说明了Lucene系统中所采用的索引文件格式

43、一些基础类和存储抽象。接下来我们来叙述一下我们在项目cLucene中重新实现这些结构时候的一些考虑。       cLucene彻底的遵守了Lucene所定义的索引文件格式,这是Lucene对于各个兼容系统的基本要求。在此基础上,cLucene系统和Lucene系统才能够共享索引文件数据。或者说,cLucene生成的索引文件和Lucene生成的索引文件完全等价。       在基础类问题上,cLucene同样封装了类似的结构。我们同样列表描述,请和前面的表3.2与3.3对照比较。 表 3.4 基础类包cLucene::util 类  说明   Arrays  没有实现,直

44、接利用了STL库中的快排序算法实现   BitVector  C/C++语言版本的实现,与java实现版本类似   Constants  常量静态类,定义了一些常量,但是与java版本不同的是,这里主要定义了一些宏   PriorityQueue  这是一个类型定义,直接利用STL库中的std::priority_queue     表 3.3 基础类包cLucene::document 类  说明   Document  C/C++语言版本的实现,与java实现版本类似   Field  C/C++语言版本的实现,与java实现版本类似   Dat

45、eField  没有实现,直接利用OpenTop库中的ot::StringUtil         存储抽象的实现上,也同样是类似于java实现。由于我们采用了OpenTop库,因此同样得以借助其中对于文件系统抽象的ot::io包来解决文件系统问题。这部分问题与前面一样,存在优化的可能。在实现的类层次上、对外接口上,均与java版本的一样。     第四节 Lucene索引构建逻辑模块分析   一、             绪论   这一个部分,我们将分析Lucene中的索引构建逻辑模块。它与前面介绍的存储抽象一起构成了Lucene的索引核心部分。无论是对外接口中的查询,

46、还是分析各种文本以进一步生成索引,都需要直接调用这部分来获得对索引文件的访问能力,因此,这部分在系统中至关重要。构建一个高效的、易使用的索引构建逻辑,即是Lucene在这一部分需要达到的目的。       从面向对象的经典思考方式出发来看,我们只需要使用继承体系来表达图3.1中的各个概念,就可以通过这个继承体系来控制索引文件的结构,然后设计合适的永久化方法,以及接受分析token流的操作,即可将索引构建逻辑完成。原理上就是这样的简单。由于两个关键的概念document和field都已经在org.apache.lucene.document中当作基础类定义过了,因此实际上Lucene在这部分

47、需要完善的概念结构还有segment和term。在此基础上继续编写各个逻辑结构的永久化方法,然后提供一个进入的接口方法,即是宣告完成了这个过程。其中永久化的部分,Lucene使用了另外实现一个代理类的方式来实现,即对于某个类X,存在XWriter类和XReader类来负责写出和读入的功能;用作永久化功能的类是被永久化的类的友元。       在接下来的分析过程中,我们按照这样一个思路,以UML图和对象体系的描述来叙述这部分的设计和实现,然后通过内部的数据流理清楚调用时序。   二、             对象体系与UML图   1.  项(Term)   这部分主要是分析针对

48、项(Term)这个概念所做的设计,包括概念所实际涉及的类、永久化类。首先,我们从图3.2和阅读参考文献3知道,项(Term)所表示的是一个字符串,它拥有域、频数和位置信息等等属性。因此,Lucene中设计了两个类来表示这个概念,如下图 图 4.1 UML图(-)   上图中,有意的突出了类Term和TermInfo中的数据成员,因为它反映了对于项(Term)这个概念的具体表示。同时上图中也同时列出了用于永久化项(Term)的代理类TermInfosWriter和TermInfosReader,它们完成永久化的功能,需要注意的是,TermInfosReader内部使用了数组indexT

49、erms和indexInfos来存储一系列项;而TermInfosWriter则是一个类似于链表的结构,通过一个other指向下一个TermInfosWriter,每一个TermInfosWriter只负责本身那个lastTerm和lastTi的永久化工作。这是一个设计上的技巧,通过批量读取(或者称为缓冲的方式)来获得读入时候的效率优化;而通过一个链表式的、各负其责的方式,来获得写出时候的设计简化。   项(term)这部分的设计中,还有一些重要的接口和类,我们先介绍如下,同样我们也先展示UML图 图 4.2 UML图(二)   图4.2中,我们看到三个类:TermEnum、TermDocs与TermPositions,第一个是抽象类,后两个都是接口。TermEnum的设计主要用在后面Segment和Document等等的实现中,以提供枚举其中每一个项(Term)的能力。TermDocs是一个接口,用来继承以提供返回值对的能力,通过这个接口就可以获得某个项(Term)在某个文档中出现的频数。TermPosit

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服