基于Lucene的大文档集合索引机制 ——文档索引的分析、设计和实现-毕业论文_第1页
基于Lucene的大文档集合索引机制 ——文档索引的分析、设计和实现-毕业论文_第2页
基于Lucene的大文档集合索引机制 ——文档索引的分析、设计和实现-毕业论文_第3页
基于Lucene的大文档集合索引机制 ——文档索引的分析、设计和实现-毕业论文_第4页
基于Lucene的大文档集合索引机制 ——文档索引的分析、设计和实现-毕业论文_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于Lucene的大文档集合索引机制文档索引的分析、设计和实现基于Lucene的大文档集合索引机制文档索引的分析、设计和实现摘要 随着企业电子化步伐的不断加快,电子商务特别是一些门户网站的信息内容也正在以惊人的速度增加着,面对如此大量的信息人们迫切需要有效的信息发现工具进行导航。于是,搜索引擎的需求呼之欲出,搜索引擎的建设和研究对于今天的信息社会来说具有很强的现实意义。本文将研究的重点集中于搜索引擎索引模块的设计和实现,本文首先研究了索引模块的相关理论,如索引的组织方法,索引的基本原理等,然后以开源代码Lucene为例,重点分析了Lucene索引模块的结构和关键代码,最后利用Lucene API函数实现了索引模块的基本功能,并利用luke工具对生成的索引进行了分析和测试。关键词 搜索引擎 lucene 索引The indexer system based on Lucenethe analysis, design and realization of indexerABSTRACT With the rapid development of internet, the on-line information, especially the information of e-commerce at some portals, increases dramatically. Facing the huge amount of information, people really need an effective tool to search what they want. Therefore, building a search engine becomes a basic requirement to a big portal. In this paper, first, We do the research about the theory of the index in full-text research, for example, the structure of index, the principle of index, and so on. Secondly, We analyze the source code of Lucene in Apache full-text search system, and master the system structure, the base data type, lastly, we design the batch index and incremental index function for the indexer by using the API function of Lucene, analyze and test indexer by the tool of luke.KEY WORDS search engine, Lucene, indexer目录引言11 搜索引擎简介21.1什么是搜索引擎22.2搜索引擎产生的背景和发展历史22 搜索引擎中有关索引模块的相关理论42.1概述42.2索引模块在搜索引擎中的重要性42.3全文索引中索引的组织方法42.4索引模块功能实现的基本原理53基于全文检索包Lucene建立索引的研究93.1 Lucene基本情况介绍93.2 Lucene检索原理93.3 Lucene的系统结构93.4 Lucene索引文件结构104 系统的设计和实现124.1 系统总体结构124.2索引构建逻辑的数据流144.3 索引过程的分析与实践154.3.1建立索引的过程154.3.2 文档索引的分析174.3.3索引的添加IndexWriter类194.3.4从索引中删除文档IndexReader类214.3.5文档索引的优化225 索引模块实现功能和分析235.1部分重点代码的说明235.2程序运行过程及结果分析245.2.1 Lucene索引工具箱LUKE245.2.2主程序运行界面245.2.3批量索引255.2.4增量索引315.2.5根据关键字删除索引345.3建立大文档索引的测试分析385.3.1测试数据来源385.3.2测试过程395.3.3测试结果分析40结论41致谢语42参考文献43引言随着信息化的高速发展,其信息量正以指数规律迅猛增长,互联网已经成为人类最重要的海量信息源,“信息迷航”和“信息过载”已经成为日益严重的问题。此时,搜索引擎以其独特的搜索功能在信息的收集和检索方面发挥了重要的作用。本文在详细阐述了搜索引擎概念及发展历程的基础上,对搜索引擎索引模块的组织方法和索引功能实现的基本原理进行了重点的研究,本文还对基于Java的全文索引引擎包Lucene索引部分进行了探究,分析了Lucene建立索引的全过程、组织结构和基本的数据类型,从而通过利用Lucene的高效性、准确性,构建搜索引擎的索引部分,在一定程度上实现了搜索引擎的索引功能模块。1 搜索引擎简介1.1什么是搜索引擎Web搜索引擎(SearchEngine)是随着web信息的迅速增加,从1994年开始逐渐发展起来的技术。实际上,搜索引擎是指因特网上专门提供查询服务的一类网站,它以一定的策略在互联网中搜集、发现信息,对信息进行理解、提取、组织和处理,并为用户提供检索服务,从而起到信息导航的目的。用户的查询途径主要包括自由词、全文检索、主题词检索、分类检索及其它特殊信息的检索(企业、人名、电话黄页等)。目前搜索引擎提供的导航服务已经成为互联网上非常重要的网络服务,搜索引擎站点也被美誉为“网络门户”。搜索引擎技术因而成为计算机工业界和学术界争相研究、开发的对象。12.2搜索引擎产生的背景和发展历史随着信息技术的不断发展,特别是互联网应用的迅速普及,电子信息爆炸似的丰富起来。目前仅Google收录的网页就超过80亿2,并且每天全球互联网网页数目以千万级的数量增加。要在如此浩瀚的信息海洋里寻找信息,就像“大海捞针”一样困难。工欲善其事,必先利其器。要在浩瀚的网络信息海洋中自如冲浪,搜索引擎己成为必不可少的利器。自1994年起至今,伴随着因特网的日益发展壮大以及Web信息量的迅速膨胀,Web搜索引擎技术为了不断满足人们对Web信息检索的需求,已经经历了三代发展阶段:第一代搜索引擎出现1994年,以集中式检索为主要特征。这类搜索引擎一般都索引少于一百万个网页,极少重新搜集网页并去刷新索引。而且其检索速度非常慢,一般都要等待10秒甚至更长的时间。在实现技术上也基本沿用较为成熟的IR (Information Retrieval)、网络、数据库等技术,相当于利用一些已有技术实现的一个WWW上的应用。在1994年3月到4月,网络爬虫World Web Worm (WWWW)平均每天承受大约1500次查询。第二代搜索引擎系统大约出现在1996年,大多采用分布式检索方案,即多个微型计算机协同工作来提高数据规模、响应速度和用户数量。它们一般都保持一个大约五千万网页的索引数据库,每天能够响应一千万次用户检索请求。1997年11月,当时最先进的几个搜索引擎号称能建立从二百万到1亿的网页索引。Altavista搜索引擎声称他们每天大概要承受二千万次查询。第三代搜索引擎系统出现在1998年到2000年期间,这一时期是搜索引擎空前繁荣的时期。第三代搜索引擎的发展有如下几个特点:(1)索引数据库的规模继续增大,一般的商业搜索引擎都保持在几千万甚至上亿个网页。(2)除了一般意义上的搜索以外,开始出现主题搜索和地域搜索。很多小型的垂直门户站点开始使用该技术。(3)由于搜索返回数据量过大,检索结果相关度评价成为研究的焦点。相关的研究又可以分为两类:一类是对超文本链的分析,在这方面始于Stanford大学的Google系统做出了很大的贡献;另一类是用户信息的反馈,Directflit系统采用的就是这种方法。(4)开始使用自动分类技术。NorthernLight和Inktomi的DirectoryEngine都在一定程度上使用了该技术。进入二十一世纪以后,随着信息多元化的增长,千篇一律的给所有用户同一个入口显然己经不能满足特定用户更深入的查询需求。同时,这样的通用搜索引擎在目前的硬件条件下,要及时更新以得到互联网上较全面的信息是不太可能的。针对这种情况,我们需要一个分类细致精确、数据全面深入、更新及时的面向主题的搜索引擎。由于主题搜索运用了人工分类以及特征提取等智能化策略,因此它比上面提到的前三代的搜索引擎将更加有效和准确,我们将这类完善的主题搜索引擎称为第四代搜索引擎。2 搜索引擎中有关索引模块的相关理论2.1概述近年来,计算机网络已经成为计算机应用领域发展最快、最热门的技术,计算机的应用已经逐步进入网络时代,人们越来越多地通过计算机网络来发布和传递各种信息,并查询自己需要的信息。全文检索技术是一种重要的关键词检索方法。所谓全文检索,就是给定一个字符串或字符串逻辑表达式,对文档库进行相应的检索,查找出与指定表达式相匹配的文档,并将包含这些文字信息的文档作为检索结果返回给用户3。全文检索技术分为两种:一种是根据检索表达式直接在原文档中匹配查找,这种方式适合于对小型文档库的检索;另一种是对文档预先建立索引,检索时对索引进行检索,这种方式适合于对一大容量的文档库的检索,如Internet网络上的文档检索。全文检索技术包含两方面的核心问题4: 一个是如何建立和维护索引库;另一个是如何提供快速有效的检索机制。面向网络的全文检索系统所处理的对象是大规模的海量数据,要实现对一它们快速有效的全文检索,主要需要从以下三方面进行考虑: (1)检索的快速响应;(2)索引库的建立与维护;(3)索引数据的压缩。2.2索引模块在搜索引擎中的重要性索引模块将Spider收集的文档进行处理,以便于有效查找的数据结构进行组织,其中就包括了全文检索索引的建立,查询服务模块从用户处获得查询请求,进行查找后将结果页面返回给用户。其中,查询模块的效率取决于索引的组织情况,也直接决定了整个搜索引擎能否实现快速响应。因此,必须对一索引进行高效组织,以实现整个搜索引擎的高效率。52.3全文索引中索引的组织方法全文检索中索引的组织方法有两种,即正排表和倒排表6。正排表是以文档的ID为关键字,表中记录项记录文档中每个字的位置信息,查找时扫描表中每个文档中字的信息直到找出所有包含查询关键字的文档。正排表结构如图2-1所示。这种组织方法在建立索引的时候结构比较简单,建立比较方便且易于维护;但是在查询的时候需对所有的文档进行扫描以确保没有遗漏,这样就使得检索时间大大延长,检索效率低下。所以通常都采用另一种字表组织方法:倒排表,其结构如图2-2所示。倒排表以字或词为关键字进行索引,表中关键字对应的记录表项记录出现这个字或词的所有文档,一个表项就是一个字表段,记录该文档的ID和字符在该文档中出现的位置情况。由于每个字或词对应的文档数量在动态变化,所以倒排表的建立和维护都较为复杂,但是在查询的时候由于可以一次得到查询关键字所对应的所有文档,所以效率高于正排表。在全文检索中,检索的快速响应是一个最为关键的性能,而索引建立由于在后台进行,效率相对低一些,不会影响整个搜索引擎的效率。图21 正排表结构图图22 倒排表结构图2.4索引模块功能实现的基本原理建立索引库的目的是为了减少查询时间,提高查询效率,同时也要兼顾到建索引更新的效率。因此,索引建立有两种策略:1)优化查询效率;2)优化索引库更新效率7。前者在建索引的时候将相同关键字的倒排表连续存放,这样在查询的时候可以将其连续读出,减少了查询的时间,但是在建索引的时候每次都要将索引库中含索引关键字的倒排表全部读出,然后把新的倒排信息加上去,最后重新写回索引库,这样做使得建索引的时间大大延长了;而当采用优化索引库更新效率策略的时候,每次将新的索引信息加到索引库的尾部,这样做使得建索引的效率得到提高,不用每次都把索引的信息读出来,但是在检索的时候需要在库中从头到尾把所有的倒排信息找出来,使得每次查询所花费的时间大大加长,降低了查询效率。因此,这两种策略各有利弊,考虑到全文检索应当首先考虑查询效率,同时兼顾索引更新效率,可以采用一种对两种策略折中的方法。建立索引时,批量输入由网络蜘蛛所搜索回来的网页,然后对这些网页首先进行网页预处理,在图中的网页parser中进行,此部分属于影响搜索引擎性能的关键技术之一,因为网页的形式、内容变化万千,一个设计良好的分析器,可以析取其中各个部分的内容、结构及特点,调整各部分对文档贡献的权值,可大大提高查询结果的精度。在经过网页parser之后,得到hit列表,hit用来记录一个词在文档中一次出现所用的数据结构。对文档集合进行parse的同时,也修改词典,把词典里没有的词加入。对hits列表进行合并,并按照文档的ID进行排序、存贮就形成了前向索引,前向索引是一个中间结果,但在查询过程中对结果进行合并时,会用到它,因此也对它进行了存贮。对前向索引,按词的ID进行重新排序,就可以得到倒排文档。此部分在图中的Indexer中进行,在产生倒排索引的同时,把索引信息写入词典中生成词典。图23 索引过程1、Hits列表:一个Hit是用来记录一个词在文档中一次出现的信息。2、前向索引表:对于文档集合中,每一文档记录其中所有出现的词(WordID)列表。在每一个WordID后, 记录该词在文档中出现的Hits列表。表21 前向索引表DocIDWordIDNhitsHits列表WordIDNhitsHits列表考虑到前向索引的可能会比较大,所以将前向索引保存在一系列的桶中,每一个桶中存放一定范围WordID所对应的索引。3、倒排索引表:前向索引经过Indexer处理后,生成倒排索引表。倒排索引,即对于词典中的词, 记录所有出现的文档的DocID,以及在每一个文档中的所有出现位置(Hits列表)。表22 倒排索引表WordIDDocIDNhitsHits列表DocIDNhitsHits列表倒排索引保存在与前向索引中相同数目的桶中,每个桶中按WordID排序。4、词典:词典实际就是一个哈希表,它以词为键值,其内容包含这个词对应的WordID、词所在的Barrel的ID,词的DocID列表在桶中的偏移量以及DocID列表中的DocID数量nDocs。通过这种结构,给定一个词,可以在常数的时间内确定词的倒排索引的位置。把整个词典装入内存中,可再大大的提高查询速度,但是这需要消耗更多的内存。表23 词典WordIDBarrelID在Barrel中偏移量NdocsWordIDBarrelID在Barrel中偏移量Ndocs3基于全文检索包Lucene建立索引的研究3.1 Lucene基本情况介绍Lucene是Apache软件基金会Jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,它提供了灵活的API函数和可以定制的数据存储结构,可以方便地嵌入到各种应用中实现具体的全文检索系统。Lucene本身只是一个组件,而非一个完整的应用,所以在集成到应用程序中时,须根据应用程序的需要设计索引数据结构,调用Lucene提供的各种借接口实现全文检索的功能。Lucene是一个高性能的Java全文检索工具包,作为一个开放源代码项目,Lucene从问世之后,引发了开放源代码社群的巨大反响,程序员不仅使用它构建具体的全文检索应用,而且将之集成到各种系统软件中去,以及构建Web应用,甚至某些商业软件也采用了Lucene作为其内部全文检索子系统的核心。Lucene以其开放性源代码的特性、优异的索引结构、良好的系统架构获得了越来越多的应用。本文在研究分析Lucene的系统结构、运作机制的基础上,设计并实现了Lucene文档索引的分析、建立和维护等方面的功能。3.2 Lucene检索原理lucene的检索算法属于索引检索,即用空间来换取时间,对需要检索的文件、字符流进行全文索引,在查询的时候对索引进行快速的检索,得到检索位置,这个位置记录检索词出现的文件路径。3.3 Lucene的系统结构Lucene作为一个优秀的全文搜索引擎,其系统结构运用了大量的面向对象的设计思想。首先是定义了一个与平台无关的索引文件格式,其次通过抽象将系统的核心组成部分设计为抽象类,具体的平台部分设计为抽象类,此外与具体平台相关的部分比如文件存储也封装为类,经过层层的面向对象编程的处理,最终达成一个低耦合、高效率、容易二次开发等的检索引擎系统。Lucene的系统结构图如下图所示:图31 Lucene的系统结构从图中我们清楚的看到,Lucene的系统由基础结构封装、索引核心、对外接口三大部分组成。其中直接操作索引文件的索引核心又是系统的重点。Lucene将所有源码分为了7个模块(在java语言中以包即package来表示),各个所属模块所属的系统部分也如上图所示。需要说明的是org.apache.lucene.queryPaser是作为org.apache.lucene.search的语法解析器存在,不被系统之外实际调用,因此这里没有当作对外接口看待,而是将之独立出来。3.4 Lucene索引文件结构为了实现高效的索引和检索,就必须具有良好的索引文件结构。Lucene的索引文件包括逻辑结构和物理结构。Lucene的每个索引文件都由一个或者多个片段Segment组成;每个片段都是一个可以被独立检索的模块,包含一定数量的文档(document),这里的文档可以是一个html页面,一个xml文档,或一个word文档。Lucene的索引文件的逻辑结构如图32所示:8图32 Lucene索引文件的逻辑结构Lucene索引文件中的核心文件包括:(l)索引项信息文件(term information file)。该文件存储了Lucene中的所有的索引项以及相关信息,主要由以下字段组成:1)字段Term Count记录了该索引文件中的索引项的个数;2)字段Document Frequency记录了有多少文档包含该索引项;3)字段Term记录了每个索引项的内容;4)字段Frequency Data指向索引频率文件(Term Frequency File);5)字段Position Data指向索引项位置文件(Term Position File);(2)索引项频率文件。该文件记录了每个索引项(term)在各个文档documenl)中的出现频率。这些信息为对搜索结构进行排序提供了重要信息。(3)索引项位置文件。该文件记录了每个索引项在各个文档中出现的位置信息,这些信息对实现精确查找exact phrase search)是必需的。4 系统的设计和实现4.1 系统总体结构本系统通过对Apache Lucene全文检索引擎工具包的深入剖析,并迸行扩展及二次开发,结合中文分词分析器,实现对中英文文档的全文索引。首先Spider到网络上下载类文本文件可以转换为文本文件的文件,如网页文件、文本文件、Word文档、PDF文档等,并将下载到的文件保存在本地的硬盘上。之后,文件处理器将Spider下载的文件转换为统一编码格式的文本文件。中文分词模块读入文件处理器处理生成的文本文件进行分词处理,并提供词元序列供索引器索引。索引模块从中文分词模块提供的词元序列中读入词元,然后对词元进行索引,并将索引结果保存到索引数据库中。使用Tomcat Web服务器发布系统的检索页面,当用户通过Web界面输入要查询的关键词并提交后,关键词被传递到搜索器中,搜索器到索引数据库中进行检索,检索到的结果经过摘要生成处理之后,作为响应发送给用户,本搜索引擎结构如图:图41 搜索引擎系统结构图文件处理器处理Spider处理器缓存到本地硬盘的网页,以xml的形式保存每一个网页需要索引的内容(包括网页的URL、处理后的文本文件路径、标题、修改日期),提供给索引器待索引的文档。文档管理器与索引器协同工作,文档管理器每获取一篇待索引文档后,将启动索引器。索引器收到启动信号后,将根据获取到的文档的具体内容,建立相应的索引字段,添加到索引数据库。系统总体数据流图如图:图42 系统总体数据流图4.2索引构建逻辑的数据流构建索引的过程即是把待索引的文件加载到全文检索库中,入库逻辑包括如下过程:1、入库者定义到库中文档的结构,入库文档结构与关系型数据库中的表结构类似,每个入库的文档由多个字段构成,假设这里需要入库的网站内容包括如下字段(Field):文章标题、作者、发布时间、原文链接等等。2、包含N个字段的文档(document)在真正入库前需要经过分词,分词的规则由语言分析器(ANALYZER)完成。3、切分后的“单词”被注册到索引树上,供查询时用,另外还需将其它不需要索引的内容入库。Lucene构建索引的数据流逻辑图如图43所示,该数据流图十分清楚地勾画出了整个索引构建逻辑这部分的设计:通过层层嵌套的类结构,在构建时候即分步骤有计划地生成了索引结构,将之存储到内存的文件系统中,然后通过对内存中的文件系统优化合并输出到实际的文件系统中。图43 Lucene构建索引的数据流逻辑图4.3 索引过程的分析与实践4.3.1建立索引的过程索引的建立需要分以下几个步骤完成:(1) 提取文本为了使用Lucene对文档数据建立索引,第一步就是要把这些需要建立索引的文档数据转换成Lucene可以处理的类型。Lucene可以处理各种各类文档,在实际的项目开发中,用Lucene对一系列的Html文档数据建立索引。首先为了使Lucene能够对这些文档数据建立索引,必须先想办法从这些PDF文档中提取出文本信息,并且使用这些提取出来的信息来构建Lucene中的Document和Field。(2) 构建Document假设现在要对一些文本文件建立索引,首先需要确定索引的数据源。对文本文件来说,数据源可以是文件名、文件的内容、文件的最后修改时间等。对于每个不同的文件,这些数据源将提供出不同的内容,一边将来存储在索引中。在Lucene中,可以把一个Document看作是这些不同内容的集合,而“文件名”、“文件内容”等名称可以看成是对不同数据源进行分类的标记,在Lucene中我们把这些标记称为Field。从根本上来讲,Lucene的Document代表了一个需要进行索引的“单元”,任何需要进行索引的“文件”都必须被转化成Document对象才能被索引和搜索到。此处在文件“二字”上加了引号,因为并非只有文件才能转化为Document类型,任何数据源经过组织都可以构建一个Document类型。进一步说,Lucene并不为任何实际物理文件建立索引,而只对Document对象建立索引。所以,建立索引的很重要一步就是将不同的数据源组织为一个Document类型的对象。事实上,我们可以把Document对象看成一种虚拟的文件,它自身带有多个数据源。从文件能够提供数据源这个角度上来看,Document对象与实际的物理文件基本类似,不同之处仅仅在于Lucene无法识别普通的物理文件而能识别一个Document类型的对象而已。(3) 分析并建索关于索引的分析,上文已详述,这里不再讨论。完成了以上三个步骤,Lucene文档索引就完成了,文档索引的完成步骤如图44所示:图44 Lucene文档索引的完成步骤4.3.2 文档索引的分析在建立索引和检索过程中,分析是很重要的一个环节。Lucene使用分析器(Analyzer)来对各种各样的输入进行分析,可以说Analyzer在Lucene开发包中占有举足轻重的地位,它的运行性能和分析能力直接影响到搜索引擎的许多环节。1、Lucene分析器Analyzer9Analyzer中文可以翻译成“分析器”,是Lucene中内置的一种工具。它主要用于分析搜索引擎遇到的各种文本。所谓分析,用更具体的话说其实就是“分词”和“过滤”。分词器就是用于对文本资源进行切分,将文本按规则切分为一个个可以进入索引的最小单位。而过滤器的功能则是对这种最小单位进行预处理,比如大写转小写,复数转单数等。这种操作可以简单(如最简单的大写转小写),也可以复杂(如根据语义改写拼写错误的单词)。如图45所示,分析器位于索引和文本资源之间,这样所有进入索引库的文本资源都应当经过分析器的分析,以此来控制索引中的内容。未经过分析器分析的文本如果直接进入索引,可能会引发各种各样数据的一致性问题,同时会降低索引的效率,进而影响整个搜索引擎的性能。图45 分析器的位置在Lucene中,所有的Analyzer均继承自org.apache.lucene.analysis.Analyzer这个基类,该基类并没有什么特殊之处,它是一个抽象类。下面以代码为例对Analyzer进行介绍。public abstract class Analyzer public TokenStream tokenStream(String fieldname, Reader reader) Return tokenStream(reader); Public TokenStream tokenStream(Reader reader) Return tokenStream(null, reader); 从上述代码中可以看出,在这个基类中实际上只定义了两个方法,这两个方法并没有实际意义,而只是提供一个供子类扩展的机制,其中,tokenStream(Reader reader)方法已经不被推荐使用。通常情况下,都需要继承Analyzer类以实现更为强大的分析功能。2、分词器(Tokenizer)和过滤器(TokenFilter)如前所述,Lucene分析器的主要作用就是对传入的文本进行切分和过滤。在Lucene中,分词器和过滤器分别是通过Tokenizer和TokenFilter类的子类来实现的。其实,从分析器功能角度来看,其本身并不能做任何事,所有工作都是依赖于分词器和过滤器完成的。一个分析器所有的工作就是将分词器和过滤器进行合理的组合,使之产生对文本分词和过滤的效果。因此,分析器使用分词器和过滤器构成了一个管道,文本在“流过”这个管道后,就成为了可以进入索引的最小单元。这也是软件体系架构中管道过滤器模式在具体实现层面的一个经典运用。3、Lucene分析器切分关键字的技术对英文而言,Lucene的分词规则很简单,因为每个单词间都有一个空格,按空格取单词即可,当然为了提高英文检索的准确度,也可以把一些短语作为一个整体,其间不切分,这就需要一个词库,对德文、俄文也是类似,稍有不同。但是对于亚洲语言来讲就有相当大的困难,如何切分紧紧相连的字符又能最大程度保持原意,有如下几种做法。(1)按照语言习惯采用精确的切分,即建立一个丰富的词库,按照词库里存在的词组对关键字进行切分。这样做的结果是关键字非常清晰,当然缺点也很明显,需要雇请专门人员进行词库设计与维护。不同的语种需要不同词库,成本巨大。中国科学院计算技术研究所在多年研究基础上研制的汉语词法分析系统ICTCLAS(Institute of Computing Technology, Chinese Lexical Analysis System),就是采用建立词库的方式,其中重要的两个文件BigramDict.dct和coreDict.dct保存了绝大多数常用词。(2)设计算法,对亚洲语言进行自动切分。因为2元是最小的查询单位,故Lucene采用2元切分法。比如“福建厦门鼓浪屿”,切分之后就是“福建、建厦、厦门、门鼓、鼓浪、浪屿”。如果采用单个字符,那么“福建”被分为“福、建”,结果很可能将“建福”一起查了出来。如果采用3元甚至多元,那么精细度又不如2元。所以2元应当是切分亚洲语言,至少是中文的最佳办法。当然上述两种算法的结合是较为完美的,由于Lucene致力于中小型应用,因此仅采用二元切分法。但是并不排除随着Lucene的发展,出现更出色的关键字切分技术。在项目过程中,采用的CJKAnalyzer类就是采用了二元切分法进行切分中文汉字。4.3.3索引的添加IndexWriter类IndexWriter类是Lucene中最重要的类之一,它的功能就是将文档加入索引,同时控制你过程中的各种参数。(1)IndexWriter的主要参数通常情况下,IndexWriter的构造函数包括了以下3个参数。1)索引存放的路径IndexWriter需要知道它要把索引创建在什么地方,因此,索引存放的路径也就必不可少。这个路径可以是一个String型的目录位置,也可以是经过封装的java.io.File对象,同时,还可以是Lucene自带的Directory类型对象。2)分析器建立索引前首先要对文本进行分析。因此,一个合适的分析器就必不可少了。IndexWriter的构造函数中不可缺少的一项就是一个继承自org.apache.lucene.analysis.Analyzer的分析器。它的主要功能是在IndexWriter将文档写入索引前,把文本信息切分成一个个可以进行索引的词条。3)是否重新创建索引IndexWriter在建立索引时,需要知道是重新建立索引,还是进行增量的索引。通过指定一个布尔型的值,就可以完成这一任务。当该布尔型的值为true时,IndexWriter不管目录内是否已经有索引了,一律清空,重新建立,而当布尔型的值为false时,则IndexWriter会在原有基础上增量添加索引。(2)IndexWriter的初始化如语句:IndexWriter writer = new IndexWriter(F:index, new CJKAnalyzer(), true); F:index为用户输入的索引保存目录,CJKAnalyzer()类是继承Lucene中的Analyzer分析器改写的一个分析器,最后一个参数true表示不管目录内是否已经有索引了,一律清空,重新建立索引。(1) IndexWriter类的具体应用以下代码为例解说IndexWriter类的具体运用Document doc = new Document();doc.add(Field.UnIndexed(file, file.getName(); doc.add(Field.UnIndexed(modified, DateFormat.getDateTimeInstance().format(new Date(file.lastModified(); writer.addDocument(doc);如上代码所示,首先创建了一个Document对象,创建了两个字段“file”和“modified”。接下来,调用了IndexWriter的addDocument方法来向索引中添加文档。向索引添加文档相当方便,只需要重复使用IndexWriter的addDocument方法就可以完成一切建立索引的过程。addDocument在Lucene中的代码如下:public void addDocument(Document doc, Analyzer analyzer) throws IOException DocumentWriter dw = new DocumentWriter(ramDirectory, analyzer, similarity, maxFieldLength); String segmentName = newSegmentName(); dw.addDocument(segmentName, doc); synchronized (this) segmentInfos.addElement(new SegmentInfo(segmentName, 1, ramDirectory); maybeMergeSegments(); 从上我们可以看出,此Lucene中的addDocument是添加索引的真正实现。其中调用了DocumentWriter类来写入文档信息,同时使用同步锁来进行目录相关的操作(如何并Segment等)。4.3.4从索引中删除文档IndexReader类对索引的文档的删除是通过IndexReader类来完成的。IndexReader类从名称上来看并不具备有删除索引的能力,但是实际上,它确实是唯一能够从索引中进行文档删除的工具。构造IndexReader的方式主要是通过它的静态方法来完成的,以下是它的部分代码:Public static IndexReader open (String path) throw IOExceptionreturn open(FSDirectory.getDirectory.(path,false),true);Public static IndexReader open(File path) throws IOExceptionreturn open(FSDirectory.getDirectory(path,false),true)Public static IndexReader open(final Directory directory) throws IOExceptionreturn open(directory,false);删除索引中的文档分为两类,一类是删除按某个特定的文档删除,一类是按字段(Field)来删除。在实际使用中,按字段(Field)具有实际运用的意义,可以用于屏蔽某些与政治立场、反动言论有关的信息。并且,直接使用文档在索引中的内部编号来进行删除相当的不方便,这并不是一个友好的编程接口。有些情况甚至是这种方式所不能处理的。在项目具体中,我们选择了按词条删除关键字。IndexReader reader=IndexReader.open(tf2.getText();reader.delete(new Term(content,tf3.getText();如上代码实现中,首先初始化IndexReader,参数为索引存放的路径。然后,使用了IndexReader的delete(Term)方法来删除一个文档。构造Term对象的方法很简单,它的构造函数中的第一个参数是字段名,第二个参数是字段中的关键字。Delete(Term)的含义就是删除所有在指定字段中含有指定关键字的文档。4.3.5文档索引的优化优化索引就是通过合并磁盘上的索引文件,以便减少文件的数量,从而也减少搜索引擎索引的时间。虽然可以通过控制各种各样的性能参数来改变磁盘上的segment数量,但是,在索引建立完成后,仍然可能存在大量未进行合并的segment。根据一般原理,在搜索的时候,搜索工具需要和磁盘上的所有索引文件打交道,如果索引segment的数量太多,则必然一个搜索器要同时打开的文件数量也会增多,因此很容易降低检索时的效率。如果是在一个多线程的环境下,多个用户同时打开这些索引进行检索,那么服务器的效率更是会显著的降低,所以,需要对索引进行优化,以增强检索速度。IndexWriter的optimize()方法就是来对索引进行优化的,它会将硬盘上的多个segment进行合并,组成一个全新的segment。需要注意的是optimize()方法并不会增加建索时的速度,反过来,它会降低建索的速度,而且由于在合并索引时,需要额外的磁盘空间来创建新的segment,因此它对磁盘空间的要求也会增加。在项目的完成过程中,运用了optimize()方法对索引进行了优化。5 索引模块实现功能和分析5.1部分重点代码的说明由本人制作的索引器实现了批量索引,增量索引,索引关键字的删除等功能,实现了索引的优化。该索引器运用了lucene1.4.3的API,运用了Analyzer子类CJKAnalyzer的二元分词法实现对中文的索引。具体代码分析如下:import org.apache.lucene.analysis.cjk.CJKAnalyzer;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.Term;引用Lucene中的各种包。其中,cjk是自建的文件夹,CJKAnalyzer是网络上流传很广的适合中文二元分词的Lucene分析器,编译完成后,将CJKAnalyzer.class和CJKTokenizer.class两个class放入cjk文件夹中,供之后的方法调用。IndexWriter writer = new IndexWriter(args1, new CJKAnalyzer(), true); 当界面中选择为批量索引时,运行以上语句初始化索引。其中args1为读入索引保存目录,newCJKAnalyzer()为引用analysis.cjk包中的CJKAnalyzer分析器,true表示需要重新建立索引; IndexWriter writer = new IndexWriter(args1, new CJKAnalyzer(), no); 当用户选择为增量索引时,第三个参数设置为no,表示在原有索引的继承上增加索引,并不改变原本已经存在的索引,采用此种方式,能够节约系统的有限资源。Document doc = new Document();doc.add(Field.UnIndexed(file, file.getName();doc.add(Field.UnIndexed(modified, DateFormat.getDateTimeInstance().format(new Date(file.lastModified()doc.add(Field.Text(title, title);doc.add(Field.Text(content, content);生成一个Document文件,加入四个Field,分别为file(索引的文件名),modified(索引的最后修改时间),title(索引的标题)和content(索引的内容)四个部分。其中title和content的获取需要去除网页中的标签脚本等干扰元素。如Pattern regex1=Ppile(script.+?|style.+?,Pattern.CASE_INSENSITIVE);content=regex1.matcher(content).replaceAll();此段代码为去除网页中脚本及css样式。writer.addDocument(doc);完成后用addDocument方法将doc加入writer中,实现索引的添加。IndexReader reader=IndexReader.open(tf2.getText();reader.delete(new Term(content,tf3.getText();此语句利用了IndexReader实现了索引的删除,将含有用户所输入关键字的索引从索引库中删除,以利于屏蔽有关敏感字眼的搜索。5.2程序运行过程及结果分析5.2.1 Lucene索引工具箱LUKELuke是Lucene的一个索引浏览器,它的作者是Andrzej Bialecki。Luke的功能十分的强大,它可以细致地显示Lucene所建立索引的内部结构,以帮助开发者更好地监视和管理索引文件。本程序利用Luke工具对所生成的索引进行分析和测试。5.2.2主程序运行界面运行主文件HtmlIndexer.java后,将会显示如图51界面:图51主程序运行界面这部分界面由四个部分构成,第一部分是选择需要索引的由爬虫爬下的文件的文件夹,第二部分选择需要存放索引的文件夹,第三部分的按钮按下索引即开始,增量索引的复选框默认为不选择,此时进行的是批量索引,即无论存放索引的目录中有无已经建立的索引,都将文件夹中的索引全部删除了重新建立。第四部分实现索引管理的删除索引功能,在文本框中输入需要删除的关键字,点击按钮,索引中即把带有关键字的索引文件删除。5.2.3批量索引批量索引建立过程需要索引的5个文件(xmu1、xmu2、xmu3、xmu4、x

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论