为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

[IT/计算机]基于Lucene的桌面搜索引擎

2017-09-02 50页 doc 254KB 28阅读

用户头像

is_624976

暂无简介

举报
[IT/计算机]基于Lucene的桌面搜索引擎[IT/计算机]基于Lucene的桌面搜索引擎 基于Lucene的桌面全文搜索引擎研究 目录 目录 ........................................................................................................................................................... 1 摘要 ......................................................
[IT/计算机]基于Lucene的桌面搜索引擎
[IT/计算机]基于Lucene的桌面搜索引擎 基于Lucene的桌面全文搜索引擎研究 目录 目录 ........................................................................................................................................................... 1 摘要 ........................................................................................................................................................... 3 Abstract ...................................................................................................................................................... 4 1 前言 ....................................................................................................................................................... 5 1.1 什么是全文检索与全文检索系统 ................................................................................................. 5 1.2 使用Lucene能做什么 ................................................................................................................... 6 1.3 本课题研究的意义 ......................................................................................................................... 6 2 Lucene搜索引擎的分析与研究 ......................................................................................................... 7 2.1 Lucene分析器——Analyzer ................................................................................................... 7 2.1.1 ANALYZER的概述 ............................................................................................................... 7 2.1.2 LUCENE内建的分析器 ....................................................................................................... 8 2.2 索引建立的过程 ......................................................................................................................... 9 2.2.1 提取文本 ............................................................................................................................... 9 2.2.2 构建DOCUMENT ............................................................................................................... 10 2.2.3 分析并建立索引 ................................................................................................................. 10 2.3 Lucene的文档格式 ................................................................................................................ 10 2.3.1 文档(DOCUMENT) ......................................................................................................... 10 2.3.2 字段(FIELD) ..................................................................................................................... 11 2.4 索引的添加——IndexWriter类 ............................................................................................ 13 2.4.1 初始化 ................................................................................................................................. 13 2.4.2 向索引添加文档 ................................................................................................................. 13 2.5 Lucene的索引文件格式简述 ................................................................................................ 14 2.5.1 索引的存放位置 ............................................................................................................... 14 2.5.2 LUCENE的索引优化 ......................................................................................................... 14 2.6 搜索的流程............................................................................................................................. 14 2.6.1 初始化LUCENE的检索工具INDEXSEARCHER ................................................................ 14 2.6.2 构建QUERY ........................................................................................................................ 15 2.6.3 搜索并处理返回结果 ......................................................................................................... 15 2.7 搜索与结果............................................................................................................................... 15 2.7.1 检索工具——INDEXSEARCHER类 .................................................................................... 16 2.7.2 检索结果——HITS ........................................................................................................... 16 2.8 Lucene的评分机制 .............................................................................................................. 17 2.8.1 理解评分的概念 ................................................................................................................. 17 2.8.2 LUCENE评分算法 ............................................................................................................. 17 2.9 倒排索引................................................................................................................................. 18 3 lucene搜索引擎的中文分词问题 .................................................................................................... 20 3.1 Lucene 中文分词算法选择 ....................................................................................................... 20 3.2 词典构造..................................................................................................................................... 20 3.3 具体实现 ...................................................................................................................................... 21 4 lucene桌面全文搜索引擎系统的分析与设计 ................................................................................ 24 4.1 桌面搜索引擎系统的功能介绍 ................................................................................................... 24 4.2 lucene桌面搜索引擎系统使用的技术 ..................................................................................... 24 4.3 lucene桌面搜索引擎系统分析 ................................................................................................. 24 4.4 lucene桌面全文搜索引擎系统的设计 ..................................................................................... 26 4.4.1 创建WINDOWS窗体应用程序 ........................................................................................... 26 4.5 为本机的文件创建索引 ......................................................................................................... 27 1 基于Lucene的桌面全文搜索引擎研究 4.5.1 选择要建立索引的目录和索引存放的位置 ................................................................. 27 4.5.2 建立索引 ......................................................................................................................... 27 4.6 搜索的效果 ................................................................................................................................ 30 4.6.1 运行搜索 .......................................................................................................................... 30 5 总结 ................................................................................................................................................... 33 致谢 ......................................................................................................................................................... 34 参考资料 ................................................................................................................................................. 35 2 基于Lucene的桌面全文搜索引擎研究 基于lucene的桌面全文搜索引擎研究 学 生: 杨刚 指导教师: 钱涛 咸宁学院 计算机科学与技术学院 湖北 咸宁 437100 摘要 Lucene是一个用Java/C#写的全文搜索引擎工具包,支持多用户访问,访问索引速度快,可以跨平台使用.全文检索技术是信息检索领域广泛使用的基本技术.它是一个优秀的开源全文本搜索技术框架.按照Lucene的框架,扩展Lucene的功能,可以将Lucene很好地嵌入到自己的搜索引擎中.本文研究了Lucene的中文切分词技术,Lucene的索引原理, 根据 Lucene的系统结构详细分析了Lucene分析器、索引包、文档等结构, 描述了利用Lucene开发定制的中文全文搜索引擎的方法,实现了一个基于Lucene的桌面搜索应用实例. 关键词: Lucene 全文检索技术 搜索引擎 索引 中文分词 3 基于Lucene的桌面全文搜索引擎研究 Desktop search engine based on lucene Student: Yang Gang Supervisor: Tao Qian School of computer Science & Technology, Xianning College, Xianning Hubei, 437000 Abstract Lucene is a full text using Java/C# to write search engine toolkit , which supports multiaccess , visits index speed quickly ,and can stride over platform usage. The full text search technology is the fundamental technology that the information retrieval field uses broadly. It is that one is excellent hold source full text searching for the technology frame originally. According to the Lucene frame norm , the function expanding Lucene's, in the search engine being able to Lucene be implanted very good to self。Unwieldy culture has studied the Lucene Chinese segments the word technology , the Lucene index principle , the system structure according to Lucene has analysed the Lucene analyzer , index structure such as bag , document detailedly , has described search engine method making use of Lucene to develop custom-built Chinese full text , has realized a example applying owing to that the Lucene full text searches for. Key words: Lucene,Full text Search technology, Search engine, Index, Segment word 4 基于Lucene的桌面全文搜索引擎研究 1 前言 Lucene开始是作为个人项目。1997年,Lucene的作者——Doug Cutting编写了Lucene。几年以后,2000年,他将Lucene放到了自己的网站上。一些人马上开始使用Lucene。2001年,Apache的人提出采用Lucene。Lucene的代码捐助也慢慢开始了,Lucene开始成为真正的合作项目。到2004年,Lucene已经有了一个强有力的开发团队。 这些年来,Lucene已经被翻译为其它多种语言版本,包括C++,C#,Perl和Python。在最初的Java以及其它各版本中,Lucene的应用相当广泛。它在各种应用中为搜索提供动力,如财富100的讨论组、商业的Bug跟踪、微软提供的邮件搜索还有数十亿页面级的 WEB搜索引擎。越来越多的人开始使用Lucene。下面我将更详细的介绍Lucene,并用它来构建一个自己的搜索引擎。 1.1 什么是全文检索与全文检索系统 全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当我们查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给我们的检索方式。这个过程类似于通过字典中的检索字表查字的过程。 全文检索的方法主要分为按字检索和按词检索两种。 按字检索是指对于文章中的每一个字都建立索引,检索时将词分解为字的组合。对于各种不同的语言而言,字有不同的含义,比如英文中字与词实际上是合一的,而中文中字与词有很大分别。 按词检索指对文章中的词,即语义单位建立索引,检索时按词检索,并且可以处理同义项等。英文等西方文字由于按照空白切分词,因此实现上与按字处理类似,添加同义处理也很容易。中文文字则需要切分字词,以达到按词索引的目的,关于这方面的问题,是当前全文检索技术尤其是中文全文检索技术中的难点,在此不做详述。 全文检索系统是按照全文检索理论建立起来的用于提供全文检索服务的软件系统。一般来说,全文检索需要具备建立索引和提供查询的基本功能,此外现代的全文检索系统还需要具有方便的用户接口、面向WWW的开发接口、二次应用开发接口等。 功能上,全文检索系统具有建立索引、处理查询返回结果集、增加索引、优化索引结构等功能,外围则由各种不同应用具有的功能组成。结构上,全文检索系统具有索引引擎、查询引擎、文本分析引擎、对外接口等,加上各种外围应用系统共同构成了全文检索系统。 5 基于Lucene的桌面全文搜索引擎研究 图1.1 全文检索系统结构 1.2 使用Lucene能做什么 Lucene可以对任何的数据做索引和搜索。Lucene不管数据源是什么格式,只要它能被转化为文字的形式,就可以被Lucene所分析利用。也就是说不管是Word、Html、PDF还是其他什么形式的文件只要你可以从中抽取出文字形式的内容就可以被Lucene所用,就可以用Lucene对它们进行索引以及搜索。 1.3 本课题研究的意义 本课题研究在于用户对本机硬盘的搜索。由于技术的进步,硬盘容量越来越大,用户在寻找某个急需的文件时难免会花费大量时间在上面,作为桌面搜索引擎,可以很好的帮用户解决这一问题。 对于普通用户来说,桌面搜索系统可以对本地硬盘上大量的文本数据进行筛选,获得文件的位置信息并可打开文件进行操作,给普通用户带来极大的方便。另外用户可以将感兴趣的站点进行下载分析,选择含有关键字的网页浏览。对于计算机相关人员尤其是网站维护管理人员来说,可以在收集的资源中快速找到需要的信息发布到网站上,另外在无版权问题时,可下载网页资源进行分析找到所需的信息,然后摘录到自己的网站上。 6 基于Lucene的桌面全文搜索引擎研究 2 Lucene搜索引擎的分析与研究 建立索引是使用搜索引擎功能的第一步。关于Lucene建立索引的这一部分内容比较多,从索引的建立到索引的优化, 索引的同步机制都是非常重要的内容,而且Lucene索引这部分内容与Lucene的搜索模块也是密切相关的。 除了检索这个必不可少的步骤外,搜索也是非常重要的一步。只有能够搜索到用户需要的内容,才算是一个好的搜索引擎。 在建立索引和检索过程中,分析是很重要的一个环节。Lucene使用分析器(Analyzer)来对各种各样的输入进行分析,可以说Analyzer在Lucene开发包中占有举足轻重的地位,它的运行性能和分析能力直接影响到搜索引擎的许多环节。 2.1 Lucene分析器——Analyzer 2.1.1 Analyzer的概述 Analyzer中文可以翻译成“分析器”,是Lucene中内置的一种工具。它主要用于分析搜索引擎遇到的各种文本。所谓分析,用更具体的话说其实就是“分词”和“过滤”。 从图4-1中可以看出,分析器位于索引和文本资源之间,这样所有进入索引库的文本资源都应当经过分析器的分析,以此来控制索引中的内容。未经过分析器分析的文本如果直接进入索引,可能会引起各种各样数据的一致性问题,同时会降底索引的效率,进而影响整个搜索引擎的性能。 正如前面所述,在Lucene中,一个分析器主要包括分词器和过滤器两种组件。分词器就是用于对文本资源进行切分,将文本按规则切分为一个个可以进入索引的最小单位。而过滤器的功能则是对这种最小单位进行预处理,比如大写转小写,复数转单数等。这种操作可以简单(如最简单的大写转小写),也可以相当复杂(如根据语义改写拼写错误的单词)。 7 基于Lucene的桌面全文搜索引擎研究 图2.1 分析器的位置 2.1.2 Lucene内建的分析器 Lucene提供了几种不同环境和需求下使用的Analyzer,最常用的如StandardAnalyzer,另外还有SimpleAnalyzer,WhitespaceAnalyzer,GermanAnalyzer等,这些都是被统一称为是Lucene内置的Analyzer。这其中的每一种Analyzer都有它自己独特的功能和用途,因此在使用时可根据不同的需要选择适合的Analyzer。 8 基于Lucene的桌面全文搜索引擎研究 2.2 索引建立的过程 在Lucene所公开的API中,仅有为数不多的方法可以在建立索引时使用。从这一方面来看,大大简化了使用Lucene建立索引的过程,提高了Lucene的易用性;从另一方面来看,在简单的API的背后,隐藏着更为复杂的操作,并且只有熟悉并掌握了这些更为复杂的操作过程,才能更加灵活地使用Lucene建立索引,逐步成为以为使用Lucene的高手。从整体来看,Lucene建立索引的过程有以下4步: 提取文本; 构建Document; 分析; 建立索引。 2.2.1 提取文本 为了使用Lucene对文档数据建立索引,第一步就是要把这些需要建立索引的文档数据转换成Lucene可以处理的类型。在使用Lucene过程中不得不面对一些更为复杂的文档数据类型,如图4-2所示。 图2.2 面对多种文档类型的处理 9 基于Lucene的桌面全文搜索引擎研究 假设现在的任务是对一系列的PDF文档数据建立索引。首先为了使Lucene能够对这些文档数据建立索引,必须先想办法从这些PDF文档中提取出文本信息,并且使用这些提取出来的信息来构建Lucene中的Document和Field。同样,当我们在需要对Word文档或者其它任何类型的文档建立索引时也面临着类似的问题。 2.2.2 构建Document 构建Document是索引建立过程的第二步。有关Lucene Document的概念在后面会有详细说明,此处不再熬述。这一步的主要目的就是将前面所提取出来的文本组装成Lucene可以识别的格式来为索引的建立做准备。 2.2.3 分析并建立索引 在提取了需要Lucene建立索引的数据并且创建了Document之后,接下来就可以调用IndexWriter类的addDocument()方法来使Lucene建立索引了。在这样的调用中,Lucene会首先对所要建立索引的数据进行分析(analysis)以使得在建立索引时可以更加容易地处理这些数据,然后索引器会按Lucene所规定的索引格式将数据写入索引文件。 2.3 Lucene的文档格式 在前面已经提到了两个概念:Document(文档)和Field(字段)。Document和Field在Lucene的索引过程中占有举足轻重的地位,而且,在Lucene的搜索部分也会涉及到相应的概念,因此可以说深入理解它们是使用Lucene的基础,下面将分别进行介绍。 2.3.1 文档(Document) 假设现在要对一些文本文件建立索引,首先需要确定索引的数据源。对文本文件来说,数据源可以是文件名,文件的内容,文件的最后修改时间等。对于每个不同的文件,这些数据源将提供出不同的内容,以便将来存储在索引中。在Lucene中,可以把一个Document看作是这些不同内容的集合,而“文件名”,“文件内容”等名称可以看成是对不同数据源进行分类的标记,在Lucene中我们把这些标记称为Field。 从根本上来讲,Lucene的Document代表了一个需要进行索引的“”,任何需要进行索引的“文件”都必须被转化成Document对象才能够被索引和搜索到。需要注意的是,此处在“文件”二字上加了引号,这是因为并非只有文件才能转化为Document类型,任何数据源经过组织都可以构建一个Document类型。更进一步说,Lucene并不为任何实际物理文件建立索引,而只对Document对象建立索引。所以,建立索引的第一步就是将不同的数据源组织为一个Document类型的对象。其实,可以把Document对象看成一种虚拟的文件,它自身带有多个数据源。从文件能够提供数据源这个角度上来看,Document对象与实际的物理文件基本相似,不同之处仅仅在于Lucene无法识别普通的物理文件而能识别一个Document类型的对象而已。 假设现在需要对一个网页执行建立索引的操作,以便在将来可以搜索到这个网页的相关内容,那么我们就需要先把这个网页转换成一个Document对象。经过分析可以知道,该网页主要有几个属性(也就是数据源)可能在将来检索时会用到,分别是网页的标题,网页的URL,网页的内容和网页的最后修改时间。因此,在为这网页构建Document对象时就应当包含这几个不同的Field。 10 基于Lucene的桌面全文搜索引擎研究 Document的基本使用方法:在document()方法中首先构造了一个Document类型的实例,然后依次往Document对象中添加了path,modified和contents 3个Field,这些Field在以后搜索时都将用到,最后返回生成的Document类型的对象doc。在对Document添加Field时,使用的是Document对象的add(Field fld)方法,例如,在添加path信息到doc对象中时,先通过f.getpath()方法获取到了文件的路径,再用Field类自带的静态方法构造出一个Field实例,然后将其传给add方法以完成添加。 2.3.2 字段(Field) 正如前面所述,字段(Field)是与文档(Document)紧密相连的一个概念,在一个Document中,它代表了不同数据源的名称。然而,在现实中,数据源所提供的数据并不是以一种一成不变的方式进行处理,对于不同的字段,人们所希望处理的方式并不相同。 对于每个Field,Lucene提供了3种方式以供用户选择进行处理,这3种方式分别是被称为“是否切词”,“是否索引”和“是否存储“。从意义上我们并不难理解这3种方式。 a.“是否切词” 表示在这个Field中的数据是否需要被切词。 b.“是否索引” 表示在这个Field中的数据是否在将来检索时需要被我们检索到,一个“不索引”的Field通常仅提供辅助信息储存的功能。 c.“是否存储” 则表示该Field内的信息是否要被原封不动的保存在索引中。 Lucene的Field类提供的构造方法支持用户构造不同类型的Field,但更为常见的是使用Field类所提供的静态方法来构造所需要的字段。在Field中,通过静态方法定义了4种不同类型的字段Text、Keyword、UnIndexed和UnStored可供使用,这4种字段在是否切词、是否索引以及是否存储等方面都有所不同,因此四种字段各有不同的用途。下面是详细介绍: (1) Text Text类型的字段代表一段需要被切词和索引的内容,这也就说明了这种类型的字段可被搜索。但是,对于这个字段的大小一定要格外小心,因为Text类型的字段有两个不同的构造函数:Field. Text(String, String)和Field. Text(String, Reader)。 如果被索引的字段是java中的String类型,那么它不仅会被索引,同时也会被存储起来,但如果是由java里面的Reader类型来为该字段提供数据源,那么它就会被索引,而不会被存储起来了。这一点在使用中往往引起一些混淆,因此在使用Text类型的字段时一定要注意这些区别。通常,Field. Text(String,Reader)用在从某个文本流数据源中获取数据,数据量一般会比较大,而在将来用户可能并不需要重现它的内容,仅是希望对其中的内容做全文检索,所以不需要去存储数据源的内容。但是希望存储数据源的内容,则只能先将其中的内容取出来保存在一个String中,再使用Field. Text(String, String)来构建需要的字段。 (2) Keyword Keyword(关键字)类型的字段不会被切词,但是会被索引并且完整的存储在索引中。这种类型的字段适合于连接地址URLs、文件系统路径信息、时间日期、人名、居民身份证号码,电话号码等。 11 基于Lucene的桌面全文搜索引擎研究 例如,需要存储一个文件的路径名信息,因为文件的路径名信息是不需要切分词的(而且切分词后反而失去了其意义),但是文件的路径名信息是需要索引和存储的,因此就可以把文件的路径名信息存储到Keyword类型的字段中。通常情况下,可以通过Field. Keyword(String fieldname, String Keyword)或Field. Keyword(String fieldname, Data data)(专门针对日期型的关键字)这两个静态方法来构造Keyword类型的字段。 (3) UnIndexed UnIndexed类型的字段既不会被切词,也不会被索引,但是它的值还是会原封不动的存储在索引中。在Field中使用Field. UnIndexed(String, String)静态方法来构建这种类型的字段。这种类型适合于处理需要和搜索结果显示在一起的内容,比如说在一个网页建立索引时可以将这个网页的URL引用地址添加到UnIndexed类型的字段中。这样在搜索到与这个网页相关的内容时,就可以将这个引用地址与搜索结果一起显示出来。 (4) UnStored Field中通过Field. UnStored(String, String)方法来构造一个UnStored类型的字段。UnStored类型的字段与UnIndexed类型的字段刚好相反,它会被切词也会被索引,但是并不会被存储在索引中。这种字段适合于索引那些并不需要以原有的形式来重视原始数据的大规模文本,比如网页的主体部分或者是内容庞大的文本文档。 在表2.1中对不同类型的字段进行了比较,中包含各个字段的特性以及通常使用的例子。 字段类型/方法 是否是否是否用途 被分词 被索引 被存储 Field. Keyword(String name, 否 是 是 电话号码、居String value) 民身份证号码、人 Field. Keyword(String, Data) 名、地名、日期 Field. UnIndexed(String, 否 否 是 文档的类型,String) 例如:Word、PDF、 Html Field. UnStored(String, 是 是 否 文档的标题和String) 内容 Field. Text(String, String) 是 是 文档的标题和 内容 Field. Text(String, Reader) 是 是 否 文档的内容 表2.1 不同字段类型比较、特性以及用途 当使用Field类所提供的静态方法来构造不同的字段时,所有的字段类型都有两个构造参数,分别代表字段名和值,也就是我们在前面提到的“键/值”对。另外,正如表格中所列举的,Keyword类型的字段除了可以接受String类型的参数作为字段值外,还可以接受Data类型的参数作为字段值,而Text类型的字段也可以接受String类型或者Data类型参数作为字段值。 假设现在需要对一个网页建立索引,该网页已经被封装为一个Page类型的对象。我们可以从这个Page类型的对象中得到的信息包括:网页的标题、网页的创建时间、网页的URL地址和网页的内容信息。 12 基于Lucene的桌面全文搜索引擎研究 Lucene的索引部分是为Lucene的搜索部分服务的,因此与Lucene的搜索部分密切相关,所以在建立索引时就应该考虑到搜索时的操作,这样才能够建立起恰当的索引字段类型。而且关于Lucene字段类型的使用也并没有统一的法则,每个人对如何使用各个字段类型都会有不同的理解,所以要深刻理解并能够灵活应用各个字段类型还需要在实际使用中逐渐积累经验。 2.4 索引的添加——IndexWriter类 IndexWriter类是Lucene中最重要的类之一,它的功能就是将文档加入索引,同时控制索引过程中的各种参数。 2.4.1 初始化 IndexWriter类的初始化过程并不复杂,它本身提供了多种构造函数。可以很方便地构造一个IndexWriter的对象。 通常情况下,IndexWriter的构造函数包括了以下3个参数。 a.索引存放的路径 IndexWriter需要知道它要把索引创建在什么地方,因此,索引存放的路径也就必不可少。这个路径可以是一个String型的目录位置,也可以是经过封装的lucene.net.Index对象,同时,还可以是Lucene自带的Directory类型的对象。 b.分析器 前面说过,建立索引前首先要对文本进行分析。因此,一个合适的分析器也就必不可少了。IndexWriter的构造函数中不可缺少的一项就是一个继承字Analyzer类的分析器。它的主要功能是在IndexWriter将文档写入索引前,把文本信息切分成一个个可以进行索引的词条。 c.是否重新建立索引 IndexWriter在建立索引时,需要知道是重新建立索引,还是进行增量的索引。通过指定一个布尔型的值,就可以完成这一任务。当该布尔型的值为ture时,IndexWriter不管目录内是否已经有索引了,一律清空,重新建立;而当布尔型的值为false时,则IndexWriter会在原有基础上增量添加索引。 2.4.2 向索引添加文档 在前面已经了解了Lucene中的Document和Field的概念,同时,也知道了Lucene是借助与IndexWriter的帮助来向索引中添加数据的。接下来,就来看看IndexWriter四如何把一个个Document对象加入索引中的。 首先创建Document对象,并分别为每个对象创建字段。然后,初始化一个IndexWriter的对象,并确定一个目录作为索引的存放目录,同时使用StandardAnalyzer作为其默认的分析器,并且设置IndexWriter清除原目录内的所有已有索引重新建立。接下来,调用IndexWriter的addDocument方法来向索引中添加文档。向索引中添加文档相当方便,只需要重复使用IndexWriter的addDocument方法就可以完成一切建立索引的过程。 需要特别注意的是,当执行完addDocument方法后,千万不能忘记调用IndexWriter的close方法来关闭它。因此会发现索引目录内除了一个Segment文件外什么都没有。只有在调用了close方法后,索引器才会将存放于内存中的所有内容写入磁盘并关闭输出流。 13 基于Lucene的桌面全文搜索引擎研究 2.5 Lucene的索引文件格式简述 Lucene的索引有其固定的格式,下面就简单的进行介绍。段(Segment) Segment是Lucene索引文件中最基本的一个单位。一个Segment是一个独立的索引,可以由IndexSearcher进行单独的查找。Lucene的工作其实就是不停地往磁盘中加入新的Segment,然后再按一定的算法合并不同的Segment以创建一个新的段。 在每个目录下都有一个“Segments”文件,该文件在每个目录中有且仅有一个,而且它的文件名只能为“Segments”。它中间保存了该目录内相关的段信息,比如有多少个Segment,每个Segment有多大等。每个Segment的所有相关文件都有相同的前缀,这个前缀通常是用三十六进制表示的索引中包含文档的数量。 2.5.1 索引的存放位置 Lucene提供了两种索引存放的位置,一种是磁盘,一种是内存。很显然,只有将索引存放在磁盘上才是最佳。FSDirectory就是File System Directory的缩写,顾名思义,它指的就是将Lucene的索引直接建立在文件系统中。通常,在使用FSDirectory时,Lucene会自动在内存中建立缓存,然后到一定时候就将索引写入磁盘。这一步操作对我们来说其实是透明的,因为我们看不见内存中的操作,而只能看见写好的索引文件系统中的内容。 2.5.2 Lucene的索引优化 索引建立完以后,并不是原封不动地放置在文件系统中,而是需要对其进行适当的优化。优化索引就是通过合并磁盘上的索引文件,以便减少文件的数量,从而也减少搜索索引的时间。虽然可以通过控制各种各样的性能参数来改变磁盘上的Segment数量,但是,在索引建立完毕后,仍然可能存在大量未进行合并的Segment。 在搜索的时候,搜索工具需要和磁盘上的所有索引文件打交道,如果索引Segment的数量太多,则必然一个搜索器要同时打开的文件数量也会增多,因此很容易降低检索时的效率。如果是在一个多线程的环境下,多个用户同时打开这些索引进行检索,那么服务器的效率更是会显著的降低,所以,需要对索引进行优化,以增加检索速度。 IndexWriter的optimize()方法就是对索引进行优化的,它会将磁盘上多个Segment进行合并,组成一个全新的Segment。需要注意的是optimize()方法并不会增加建索时的速度,反过来,它会降低建索的速度,而且由于在合并索引时,需要额外的磁盘空间来创建新的Segment,因此它对磁盘空间的要求也会增加。 通常情况下,optimize()方法不应当在索引建立的过程中被调用,而应当是在对大批量索引建立完成后再进行调用。这是因为在对索引进行优化时,磁盘的I/O操作频繁,如果太过频繁的进行索引的优化,会导致系统吞吐量大幅降低。 2.6 搜索的流程 如果检索的过程过于复杂,那么搜索引擎也就失去了其优势。本小节主要介绍使用Lucene进行检索的流程。 2.6.1 初始化Lucene的检索工具IndexSearcher 14 基于Lucene的桌面全文搜索引擎研究 IndexSearcher是Lucene中最基本的检索工具,所有的检索工具都会用到IndexSearcher检索工具,但是在使用IndexSearcher之前,还要做一些准备工作,即对检索工具IndexSearcher进行初始化。 初始化IndexSearcher,需要设置索引存放的路径,这样才能让查询器定位索引,用于后面进行搜索。如下为一个实例化IndexSearcher的过程: Searcher searcher = new IndexSearcher(indexDir); 返回的结果是IndexSearcher类的一个实例,indexDir表示索引文件的存放路径。当然,初始化IndexSearcher不止这一种方式。 2.6.2 构建Query Query的中文意义就是“查询”。在Lucene中,它是一个很重要的概念,就是指对于需要查询的字段采用什么样的方式进行查询,如模糊查询、语义查询、短语查询、范围查询、组合查询等。正是因为Query的存在,Lucene才有了非常丰富的查询语言。 在使用Query前,需要首先生成一个Query对象。Lucene既允许直接生成一个Query型的对象,也允许使用QueryParser类的Parse ()方法来返回一个Query 型的对象。这两种方法在功能上是完全一样的,只是后者在使用时更方便一些,而前者则更为灵活。 2.6.3 搜索并处理返回结果 在构建完Query对象后,就可以使用前面已经IndexSearcher工具来进行检索了。IndexSearcher提供了良好的检索接口,用户只需简单地将Query对象传入,就可以得到一个返回结果。当然,这个过程看似简单,其中也有许多值得思考的问题,如检索的结果排序,过滤等。 2.7 搜索与结果 15 基于Lucene的桌面全文搜索引擎研究 在本节将介绍如何使用Lucene进行索引的检索。同时,又如何对返回的结果进行处理。 2.7.1 检索工具——IndexSearcher类 Lucene中使用IndexSearcher类来对索引进行检索。IndexSearcher类继承自Searcher基类,是Lucene中最重要的一个检索用类。前面说过,在初始化一个IndexSearcher类时最重要的就是要告诉它索引存放的路径,只有这样,检索工具才可以定位索引,从而完成查找的任务。以下是IndexSearcher的所有构造函数: public IndexSearcher (String path) throws IOException{ this (IndexReader.open(path),true); } public IndexSearcher(Directory directory)throws IOException{ this (IndexReader.open(directory),true); } public IndexSearcher(IndexReader r){ this (r, false); } private IndexSearcher (IndexReader r, Boolean closeReader){ reader = r; this. closeReader = closeReader; } 可以看到,IndexSearcher一共提供了四种构造函数来初始化一个IndexSearcher对象。第一个方法最为简单,它直接使用了索引存放的路径作为参数来构造对象。第二种方式则是使用Directory类型的对象来构建IndexSearcher。第三种是直接使用IndexReader来初始化一个IndexSearcher对象。第四种则是在第三种的基础上加一个布尔型的开关,用于判断在关闭IndexSearcher时是否要关闭所带的IndexReader对象。可以看出,实际上,无论传入的参数类型是什么,IndexSearcher最终都还是使用IndexReader来作为实际的索引目录读取器。前三种构造函数均首先根据传入的参数生成一个IndexReader对象,然后调用了第四种构造方法来完成IndexSearcher的初始化工作。 在初始化的工作完成之后,在进行搜索之前还需要构建一个Query对象。 在IndexSearcher类中也有一个close方法。事实上,它关闭的并非Searcher对象本身,而是关闭Searcher对象内部所带的IndexReader对象。 2.7.2 检索结果——Hits 在搜索完成之后,就需要把搜索结果返回并显示给我们,只有这样才算是完成了搜索的任务。在Lucene中搜索结果的集合是用Hits类的实例来进行表示的。所有的search方法都返回一个类型为Hits的对象。 Hits对象中主要有以下几个经常使用的方法。 length():返回搜索到结果的总数量。 doc(int n):返回第n个文档。 id(int n):返回第n个文档的内部ID号。 score(n):返回第n个文档的得分。 16 基于Lucene的桌面全文搜索引擎研究 其中,1ength()方法和doc(int n)方法共同使用,就可以遍历结果集中的所有文档记录。不过有一点值得注意,如果一个结果集含有100000条记录,而Hits对象一次性就把检索结果全部返回,那么这个Hits对象的结果就会大不一样。 对这个问题做了细致的考虑,它并不是一次性将所有的结果返回,而是采取一种懒惰(Lazy)的方式来加载返回结果,即当用户将要访问某个文档的时候,Hits对象在内部对Lucene的索引又进行了一次检索,才将这个最新的结果返回给我们。 关于Hits对象的使用,在前面的章节中已经给出了许多例子,在建立完索引后,初始化一个IndexSearcher来进行检索。对于检索结果,在代码中使用了Hits对象所提供的大多数方法,比如获取文档、获取文档ID和获取文档评分等。代码在运行时,首先要求输入要查询的字符串,然后根据输入的查询字符串进行相应的检索。 在开发相关应用时,简便的方法是当我们检索完毕后,可直接将返回的Hits对象存入我们的session中,然后根据我们的需要进行相关查询。不过这里要注意一点,由于Hits对象被放入session中,并不适合存入大量文本。 2.8 Lucene的评分机制 前面提到过,使用Hits对象可得到某个文档的得分。 2.8.1 理解评分的概念 评分是搜索引擎中很重要的一个概念。通常情况下, 当我们输入一个关键字,搜索引擎接收到信息后即可开始进行检索。对于检索到的结果,需要按一定的顺序返回给我们。因此,需要引入一种机制来对检索结果进行排序,以便更加合理的将结果返回给我们。 评分机制就是对检索结果按某种进行评估,然后按分值的高低来对结果进行排序。同时,对于一个商用的搜索引擎来说,评分机制是其收入来源的重要部分。例如某公司向搜索引擎缴纳一定数量的费用,则该搜索引擎就将其搜索结果中关于该公司的部分公值加大,以便能在检索结果返回给我们时让该公司获得更加靠前的位置。这种做法增加了我们浏览该公司网页和产品的机会,无形之中也给该公司带来了更大的社会影响和潜在商机。因此,评分机制从各方面来说都是相当重要的。 2.8.2 Lucene评分算法 那么,下面将详细介绍Lucene中是如何确定各个Document评分的,该功能的基本原理。 文档的得分是在我们进行检索时实时计算出来的。如果在建立索引时就已经将每个文档的得分计算好,那么当我们输入任何关键字时,得分最高的文档都会被排在返回结果的最前面,这显然是不合理的。 因此,所有文档的得分应当是都与我们输入的关键字有关系,而且是实时运算的结果。其实,所谓得分,可以简单理解成是某个关键字在某文档中出现的频率。 下面所示公式(2.1)就是Lucene用于计算某个关键字在对应于某个文档的得分。 (2.1) 在Lucene得分公式中,已经包含了影响文档评分的各种因素。在表2.2中详细介绍了每一种因素对搜索结果评分的影响作用。 表2.2 Lucene得分公式的解释 17 基于Lucene的桌面全文搜索引擎研究 因素 在公式中的作用描述 tf(t in d) 词条t在文档d中出现的词频 idf(t) 词条t在文当中的倒排词频 boost (t.field in d) 在索引过程中设置的字段参数 lengtfNorm(t.field in d) 字段的标准化值,表明在字段中存储了多少词条, 这个数值是在索引过程中计算出来的,并且也存储在索 引中 coord(q.d) 协调因子,它的计算是基于文档d中所包含的所有 可供查询的词条数量 queryNorm(q) 在给出每个查询条目的方差和后,计算某查询的标 准化值 2.9 倒排索引 18 基于Lucene的桌面全文搜索引擎研究 倒排索引是一种面向单词的索引机制,利用它可以提高检索时的速度。通常情况下,倒排索引结构由“词典”和“出现情况”两部分组成。对于每一个单词,都会有一个词汇列表记录单词在所有文档中出现的位置,这些位置可以是单词的位置(文本中的第几个单词)也可以是字符的位置(文本中的第几个字符)。 如果使用正常的索引结构,建立的是“文档到单词”的映射关系,在使用倒排索引技术后,建立的是“单词到文档”的映射关系,那么这两种映射关系到底有何不同呢,它们各自有什么有缺点呢,下面举例说明这两种映射关系的差别。 假设现在有两篇文档:文档A和文档B。文档A的内容是:This is a dog。文档B的内容是:The dog is a kind of animal。 下面对这两个文档建立索引结构。 如果建立的是一般的索引结构,那么会有如表2.3所示的关系。 表2.3 一般的索引格式示例 文档编出现单出现次文档编出现单出现次号 词 数 号 词 数 A dog 1 kind 1 B dog 1 animal 1 从中可以看出,一般的索引结构是以文档为标准建立索引结构的,即它记录的是一篇文档中所有单词出现的情况。比如在文档B中dog,kind、anima1均出现了一次。然而,用户在进行检索时,都是输入关键字进行查询,如果使用这种索引结构,在查询某一关键字时往往需要遍历所有的索引,当索引量非常大时,效率会成为一个很大的问题。 倒排索引恰恰解决了这个问题它是以关键字为标准建立索引的。 从表2.4可以看出,倒排索引是以单词为标准建立的索引结构,它描述了一个单词在所有文档中的出现情况,比如说“dog“在文档A和文档B中分别出现了一次,而单词“kind“只在文档B中出现了一次'。 表2.4 倒排索引结构示例 单 词 出现的出现次单 词 出现的出现次 文档 数 文档 数 dog animal B 1 A,B 1,1 kind B 1 通过比较可以发现,一般的索引结构建立的是一种“文档到单词”的映射关系,而倒排索引建立的则是一种“单词到文档”的映射关系。因为在日常的检索中,通常都是按照关键字进行检索的,所以,倒排索引可以更好地适合这种检索机制的需要。这也是到排索引如今被大规模使用的原因。 19 基于Lucene的桌面全文搜索引擎研究 3 lucene搜索引擎的中文分词问题 所谓分词,指的就是将一个完整的句子划分为一个个词条(Token)过程。这种词条应当满足某种语言规则,以便于为其建立索引。只有通过这样的方式,才能完成对一种语言的分析和检索。 3.1 Lucene 中文分词算法选择 分词系统主要关心的是两个指标:切分速度和切分精度。由于搜索引擎与自然语言的理解,自动翻译不同,在切分精度方面要求不是很严格,更注重切分速度[19]。在Lucene 中通常采用基于规则的分词方式。主要有单字切分,二分法。 单字切分,顾名思义,就是按照中文一个字作为一个词的方式进行分词。以这种方式切分出来的词再进行索引,称之为字索引。很显然,这不是一种很好的分词方式,因为随着索引的增大,相应索引条目的内容会不断增大,严重影响效率。另外,当用户对索引进行检索时,如果用户输入 5 个字,则相当于要对索引进行 5 次 检索,严重的影响效率。单子切分除了影响索引效率和检索效率外还影响检索的结果。比如说查询“上海”时,由于单子切分把“上海”切分成两个词:“上”和“海”,这样“海上”也可能被检索出来。显然这结果并不是用户想要的。 所谓二分法,就是指每两个字进行一次切分。如对“天涯若比邻”这样一个词组进行二分法切分,则结果如下;天涯/涯若/若比/ 比邻。这种切分方式完全不考虑词义、语境、机械地对语句进行处理。虽然结果看起来有些可笑,然后,在很长一段时间内,它一直是中文分词的一种很方便的方式[20] 。根据这样分词效果建起来的索引会存有大量垃圾词汇,有可能使用户根本不可能检索的词。因此,它也不是很好的方式。 词库分词被认为是一种比较理想的中文分词方式。所谓词库分词其实就是用一个已经建立好的词的集合按照某种算法去匹配目标,当遇上集合中已经存在的词时,就将之切分出来。例如词库中已经存在“天涯若比邻”这个词时,分词器就会把它当作是一个词条加入索引。很显然,对于这种分词方式,词库的建立是关键。通常,词库的建立需要统计大量的内容,然后根据各种词出现的频率、概率再来进行筛选,最终决定什么词应当放入词库。另外,一些更加高级的词库还加入了语义和词性的标注,甚至还有不同的权重。 为了能够使得分析器功能更加符合汉语习惯,并提高分词的准确性,本文选择采用前向最大匹配切分算法。并且根据汉语中词条分布情况,本文中将最长词条长度设为4。 最大匹配切分算法中规定最长词条长度 M。首先字符指针指向待切分字符串的 串首,读取前M 位字符作为子串。到切分词典找查找该子串,如果不存在,则去除 子串中最后一位字符,将剩下的字符串作为子字符串,重复上面过程,直到在词典中查找到子字符串或者子字符串长度变为1,将子字符串作为词,然后字符指针指向子字符串后面的第一位字符,继续上面过程,直到字符串扫描结束。例如,待处理字符串为“汉字多为表意文字”,取字符串“汉语多为表”(假设比较的步长为4,本文步 长 step 都取4)与词典进行比较,没有与之对应的词,去除“表”字,用字段“汉语多为” 进行匹配,直至匹配到“汉语”为至,再取字符串“多为表意”,循环到切分出“文字” 一词。 3.2 词典构造 20 基于Lucene的桌面全文搜索引擎研究 分词词典是汉语自动分词系统的一个基本组成部分,自动分词系统所需的各类信息都要从分词词典中获取,分词词典的查询速度直接影响到分词系统的速度。 本文采用基于整词二分的分词词典机制,这是一种广为使用的分词词典机制。 其结构可分为:首字散列表和词典正文两部分。由首字的散列值得到词典正文的位置。首字散列表为词语的首个汉字,通过计算其散列值可以快速定位词典正文的位置。词典正文是以词为单位的有序表,通过整词的二分快速查找可以快速找到所查询词的位置。对于每个字符串,其散列值随散列算法不同而不同, 由于Lucene中使用的是 UTF-8 编码,本文采用相应的散列算法。散列公式: 其中: 表示字符串的第 i个字符的Unicode 编码的值,n 是字符串的长度, ^表示求幂。 由于在java 中一字符由双字节组成,每个汉字由一个字符表示。所以词典中首由于选择的分词算法中,对长度超过4 以及长度为 1 的词不进行查找,所以本 文的词典过滤了长度为 1 以及长度超过4 的词。这样不仅减小词典所占据的内存空间,同时提高了查询字典的效率,从而提高整体查询的速度。 3.3 具体实现 Lucene 中实现自己的分析器,需要实现自己的Analyzer,Filter,Tokenizer 类。 Tokenizer 对字符串进行分析得到词汇单元以及词汇单元的位置信息,即一系列的 Token, 然后Filter 对得到的Token 进行过滤,最后由Analyzer 提供接口。 本文实现MyAnalyzer,MyFilter,MyTokenizer 分别继承Analyzer,Filter,Tokenizer 类。另外,因为本文实现基于词典的中文分词,所以提供了 WordLibService 类,来 实现关于词典相关的功能。 下面介绍MyAnalyzer,MyFilter,MyTokenizer 以及WordLibService 提供的功能。 MyTokenizer 主要完成分词功能,分词流程如图如下。其主要分析原理如下:将字符分为三种类型:中文字符,英文字母或数字,其他字符。MyTokenizer 从字符串中每次读入一个字符,如果该字符是中文字符或者英文字母或数字时,将该字符加入缓存。当读入的字符是其他字符,或者读入的字符与缓存中字符类型不一致,或 者缓存中的字符数到达最大词长时,处理缓存。重复以上过程,直到处理完字符串。其中处理缓存有两种情况:一、缓存中内容是中文字符,此时MyTokenizer 根据最大 匹配切分算法对内容进行分析,得到一个词,并且从缓存移出该词;二、缓存内容 为英文字母或数字,此时处理操作为:该将该内容作为一个词汇,并且清空缓存。 MyFilter 主要功能为过滤停用词。MyFilter 中包含停用词列表,如果MyTokenizer 分词得到的项中的词汇为停用词则过滤该项。根据中文语言的特点,本文实现的停 用词列表中补充了“啊”,“阿”,“哎”,哎呀“,哎哟”,“俺们”等中文词汇。 MyAnalyzer 向用户提供接口,返回MyFilter 过滤后的项。 WordLibService 主要提供了三个功能:创建词典、载入词典、更新词典。创建词 典:将词库按照每行一词存储于文件中,程序将词库文件中的词读入内存,并且根据以首字作为键,以该字为词首的词组成的有序列表作为值的结构组织成词典,以 HashMap 对象存储于内存中,然后将HashMap 对象序列化存储于本地磁盘文件中。词典中载入词典:将储存于本地磁盘文件凡序列化得到HashMap 对象,即为以键值 对的形式的词典,读入内存。用来判断字符串是否存在于词典中。更新词典:用户 可以根据自己需要以每行一词的格式添加自己的词,更新词典时,程序会先在词典 中查找是否存在该词,如果不存在则将该词添加到词典中。 21 基于Lucene的桌面全文搜索引擎研究 SChinese为空, SEnglish为空 Pointer++ SChinese 和SEnglish SChineseSEnglish为空, 为空, 为空, N Y N Y Y Pointer-- Pointer-- SChinese+=Char,SEnglish为SChinese长度是否SEnglish+=Char,空, 等于MaxChinese SEnglish长度是否等 于MaxEnglish, N Y Y Y SEnglish作 为词 N SEnglish作 为词 在词典中包含 SChinese, N N Y Y SChinese=SChinese-lastChar, Pointer--; SChinese作 SChinese长度为1, 为词 图3.1 MyAnalyzer分词器流程图 22 基于Lucene的桌面全文搜索引擎研究 下面对StandardAnalyzer分词器和MyAnalyzer分词器进行比较。 StandardAnalyzer [一] [种] [面] [向] [搜] [索] [引] [擎][Lucene] [的] [中] [文] [分] [词] [方] [法] MyAnalyzer [一种] [面向] [搜索引擎] [Lucene] [中文] [分词] [方法] 对“一种面向搜索引擎Lucene 的中文分词方法”进行分析,从表中结果不难发现,StandardAnalyzer 将每个汉字作为一个词,MyAnalyzer 采用的基于词典的最大匹配切分算法分词。显然MyAnalyzer 的分词结果更符合汉语的习惯。 23 基于Lucene的桌面全文搜索引擎研究 4 lucene桌面全文搜索引擎系统的分析与设计 通过前面对lucene的一些介绍,本章将使用lucene来制作一个搜索引擎系统。该搜索引擎可以为一些在本地硬盘上的部分文件建立索引,然后检索这些文件。 4.1 桌面搜索引擎系统的功能介绍 该系统有索引和搜索两大功能: 索引功能中用户可以选择要被索引的文件的目录,可以是整个电脑硬盘,可以是磁盘的某个分区,也可以是某个盘中某个文件。这个搜索引擎系统默认了可以对doc文件,txt文件,HTML文件,pdf文件,ppt文件等10种文件格式的索引和检索,当然,可以修改App.config的内容来增加或修改所要检索的文件格式。系统会默认把索引的文件目录放在“D:IndexDri”文件中。当读取索引时,只需要选择已生产索引的目录即可。 搜索功能中用户选择生成索引的目录(但不选择时系统会默认目录为“D:IndexDri”),然后输入想要搜索的关键字,系统会显示出与关键字相关的信息,如路径、内容、大小、得分排名等。 4.2 lucene桌面搜索引擎系统使用的技术 Lucene桌面全文搜索引擎系统使用到了中文分词技术,运用到MyAnalyzer分词器。MyAnalyzer分词器带有词库分词方式,具有词典功能,其运用最大匹配切词算法,对索引内容进行匹配检测,其运行效率相对而言是比较高的。 4.3 lucene桌面搜索引擎系统分析 下面展示lucene桌面搜索引擎系统的流程图,如图4-1.从图中可以清楚看到该搜索引擎系统的主要功能。 24 基于Lucene的桌面全文搜索引擎研究 创建索引 索引 显示所有被成 功索引的文件 索引保存目录 读取索引 搜索 输出结果 Y 输入关键字 是否有搜 索结果, 结果为空 N 图4.1 lucene桌面搜索引擎系统的流程图 25 基于Lucene的桌面全文搜索引擎研究 从流程图中可以看出,系统可以自由创建索引,然后再读取索引和搜索结果。但索引目录中没有记录索引关键字的文件时,系统就会显示一个空的结果。读取索引显示结果会显示一个ID号,并一致排下来,搜索结果会显示其得分,并按分数的降序排列。 4.4 lucene桌面全文搜索引擎系统的设计 有了系统流程图以后,对该系统的实现就有了一个明确的目标。 4.4.1 创建windows窗体应用程序 首先建一个windows项目,设计一个windows窗体,窗体中有索引和搜索两大功能,索引功能中有创建、添加等功能。用户可以自定义索引目录,可以是一个文件夹,可以是一个硬盘分区,也可以是整个电脑硬盘。如图4-1显示的索引界面。 图4.2 窗体索引界面 另外一个功能是搜索的,如图4.3 。其界面与索引较为相似。 26 基于Lucene的桌面全文搜索引擎研究 图4.3 窗体搜索界面 4.5 为本机的文件创建索引 4.5.1 选择要建立索引的目录和索引存放的位置 首先,确认要建立索引的目录,这个可以由用户自己去选择。选择要保存索引目录时,系统会自动默认在电脑D盘下建立IndexDir目录作为索引的存放目录,当然,也可以自己选择要存放的地方。当以上内容都选择完毕后,就可以为这些文件建立索引了。 4.5.2 建立索引 通过调用App.config配置文件来选择索引什么类型的文件,一般来讲是doc,txt,ppt,html和pdf格式的文件最为常见。 如何获取配置文件App.config的能容呢,在App.config文件中,添加下面几行代码: 这是索引要检索的文件格式,用户可以修改扩展名来改变系统检索的文件类型。 配置完索引格式后,下一步就是如何调用刚才配置的文件。 private void InitExtention() { string filesTypes = ConfigurationManager.AppSettings["IndexFileType"]; string[] filesTypeList = filesTypes.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); foreach (string item in filesTypeList) { extentions.Add(item); } string ooxmlTypes = ConfigurationManager.AppSettings["OOXMLFileType"]; string[] ooxmlTypeList = ooxmlTypes.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); foreach (string item in ooxmlTypeList) { OOXMLType.Add(item); } } 27 基于Lucene的桌面全文搜索引擎研究 这段代码讲述了如何获取配置文件中的内容。然后再通过CreateFileIndex()函数调用上面的函 数,这样就可以读取配置文件的内容了。 如何建立索引,这是其中主要代码: public void Create(string dirPath) { FileInfo fileInfo; List deleteList = new List(); foreach (string path in Directory.GetFiles(dirPath)) { if (isStop) return; fileInfo = new FileInfo(path); if (isRewrite) { AddFileDocument(fileInfo); } else { int deleteIndex = IndexInfo.GetDocumentIndex(indexDirectory, fileInfo); if (deleteIndex >= 0) { deleteList.Add(deleteIndex); AddFileDocument(fileInfo); } else if (deleteIndex == -1) { AddFileDocument(fileInfo); } } this.writer.Optimize(); } foreach (string path in Directory.GetDirectories(dirPath)) { Create(path); } if (Directory.GetDirectories(dirPath) == null) { this.writer.Optimize(); this.writer.Close(); } if (deleteList.Count > 0) { ControlIndex.DeleteDocument(indexDirectory, deleteList); } } 28 基于Lucene的桌面全文搜索引擎研究 索引文件会覆盖原来的索引文件。索引文件界面如下图所示: 新的 图4.4 索引文件界面 索引最下面可以看到已被索引的文件数以及完成本次索引的时间。 读取索引后会显示索引的序列号、名称、路径、大小等等属性,如图5-4: 图4.5 读取索引目录 29 基于Lucene的桌面全文搜索引擎研究 4.6 搜索的效果 4.6.1 运行搜索 索引成功建立后,接下来就让我们试试搜索引擎的搜索功能。假设我们现在要搜索“lucene”,那么就可直接在搜索界面的关键字栏中输入“lucene”二字,然后点搜索,搜索引擎就会自动执行搜索功能,可以直接从看到搜索的结果,效果如图5-4所示。 图4.7 搜索的效果(1) 图 4.8 搜索的效果(2) 30 基于Lucene的桌面全文搜索引擎研究 从搜索结果中,我们可以看到要索引的文件的一个排名情况,按降序排列。同时也可以看到要搜索的文件的文件名、路径、大小和内容等等。 下面是实现搜索索引主要代码: public void Query_Phrase(string query_) { this.query_searcher = query_; QueryParser parser_name = new QueryParser("name", new StandardAnalyzer()); query_name = parser_name.Parse(this.query_searcher); QueryParser parser_content = new QueryParser("content", new StandardAnalyzer()); query_content = parser_content.Parse(this.query_searcher); QueryParser parser_content_stream = new QueryParser("contentsStream", new StandardAnalyzer()); query_content_stream = parser_content_stream.Parse(this.query_searcher); } public void InitSearcher() { try { searcher = new IndexSearcher(this.indexDir); if (this.IsSearchName) { hits_name = searcher.Search(query_name); } if (this.isSearchContent) { hits_content = searcher.Search(query_content); } if (this.isSearchContentStream) { hits_content_stream = searcher.Search(query_content_stream); } } catch (Exception e) { throw e; } } 获取索引文件后,系统进行的下一步动作就是把搜索的结果显示出来,主要代码如下: /// /// 获取查询结果集 /// public DataTable GetFileResult() { DataTable result = new DataTable("searcher_result"); DataColumn name = new DataColumn("name", Type.GetType("System.String")); DataColumn path = new DataColumn("path", Type.GetType("System.String")); DataColumn lasttime = new DataColumn("lasttime", Type.GetType("System.String")); 31 基于Lucene的桌面全文搜索引擎研究 DataColumn content = new DataColumn("content", Type.GetType("System.String")); DataColumn extention = new DataColumn("extention", Type.GetType("System.String")); DataColumn length = new DataColumn("length", Type.GetType("System.String")); DataColumn score = new DataColumn("score", Type.GetType("System.String")); result.Columns.Add(name); result.Columns.Add(path); result.Columns.Add(lasttime); result.Columns.Add(content); result.Columns.Add(extention); result.Columns.Add(length); result.Columns.Add(score); DataRow resutl_row; if (hits_name != null) { int index = 0; for (; index < hits_name.Length(); index++) { resutl_row = result.NewRow(); resutl_row["name"] = hits_name.Doc(index).GetField("name").StringValue(); resutl_row["path"] = hits_name.Doc(index).GetField("path").StringValue(); resutl_row["content"] = hits_name.Doc(index).GetField("content").StringValue(); resutl_row["length"] = hits_name.Doc(index).GetField("length").StringValue(); resutl_row["extention"] = hits_name.Doc(index).GetField("extention").StringValue(); resutl_row["lasttime"] = hits_name.Doc(index).GetField("lasttime").StringValue(); resutl_row["score"] = hits_name.Score(index); result.Rows.Add(resutl_row); } } if (hits_content != null) { int index = 0; for (; index < hits_content.Length(); index++) { resutl_row = result.NewRow(); resutl_row["name"] = hits_content.Doc(index).GetField("name").StringValue(); resutl_row["path"] = hits_content.Doc(index).GetField("path").StringValue(); resutl_row["content"] = hits_content.Doc(index).GetField("content").StringValue(); resutl_row["length"] = hits_content.Doc(index).GetField("length").StringValue(); resutl_row["extention"] = hits_content.Doc(index).GetField("extention").StringValue(); resutl_row["lasttime"] = hits_content.Doc(index).GetField("lasttime").StringValue(); resutl_row["score"] = hits_content.Score(index); result.Rows.Add(resutl_row); } } if (hits_content_stream != null) { int index = 0; for (; index < hits_content_stream.Length(); index++) 32 基于Lucene的桌面全文搜索引擎研究 { resutl_row = result.NewRow(); resutl_row["name"] = hits_content_stream.Doc(index).GetField("name").StringValue(); resutl_row["path"] = hits_content_stream.Doc(index).GetField("path").StringValue(); resutl_row["content"] = hits_content_stream.Doc(index).GetField("content").StringValue(); resutl_row["length"] = hits_content_stream.Doc(index).GetField("length").StringValue(); resutl_row["extention"] = hits_content_stream.Doc(index).GetField("extention").StringValue(); resutl_row["lasttime"] = hits_content_stream.Doc(index).GetField("lasttime").StringValue(); resutl_row["score"] = hits_content_stream.Score(index); result.Rows.Add(resutl_row); } } return result; } 我们先用用GridView控件绑定数据,然后再把所搜索的结果显示出来。然后,可以通过得分排名索引出的文件的重要程度。 5 总结 在前面所有的内容中,先是讲解了Lucene的历史和现状,Lucene的中文分词问题,Lucene的用法,Lucene的索引机制,搜索流程等一系列问题。然后借助于Lucene的帮助,我们建立了自己的搜索引擎,实现了对doc文件,txt文件,HTML文件,pdf文件,ppt文件等10种文件格式的索引和检索。 本论文只是叙述了对lucene搜索引擎的一个研究过程,了解lucene搜索引擎的是如何实现索引和检索功能的。当然,这里只是讲述lucene搜索引擎的一些基本常用功能的实现,因为lucene是一个很强大的搜索引擎架构包,如果想要深入了解它,还需要以后不断研究和学习。 我们所做的搜索引擎只是用一段代码演示了作为一个搜索引擎的最基本的功能,离服务性搜索引擎还相去深远。比如一个友好的用户界面,检索结果的直接访问,关键字分析的能力,对中文很好的支持等等,这些都是评价一个搜索引擎好坏的参数。 33 基于Lucene的桌面全文搜索引擎研究 致谢 首先要感谢钱涛老师,在整个毕业设计过程中给我提供了毕业设计所需要的很多资料,帮助解答毕业设计中遇到的问题。其次要感谢实验室的老师们,是他们在毕业设计中为我准备好了毕业设计的工作环境。还要感谢的就是网络,网络上的信息量是惊人的,它又是一位很好的老师,无论你遇到什么问题,都可以在网络上找到答案,如果真的没有你问题的答案,你还可以提问,总会有人知道答案的。再次是要感谢和我一起做毕业设计的同学们,正是有了他们,我们才在遇到问题时,相互鼓励,最终解决了问题,圆满地完成了毕业设计的各项工作。 34 基于Lucene的桌面全文搜索引擎研究 参考资料 [1] (美)Karli Watson Christian Nagel C#入门经典(第四版) 2010年 清华大学出版社 [2] 张延铎等 人工智能 2006年 清华大学出版社 [3] 李刚 宋伟 邱哲等 Ajax+Lucene构建搜索引擎 2006年 人民邮电出版社 [4] (美)高斯帕那(Gospodnetic,O.),(美)哈特赫(Hatcher,E.) 著,谭鸿 等译 Lucene in Action中文版 2007年 电子工业出版社 [5] 何培 基于Lucene的mp3搜索器 2005年 清华大学出版社 [6] 符文彬等 基于JAVA的全文索引引擎Lucene简介 2005年 电子工业出版社 Lucene入门与使用 2004年 电子科技大学出版社 [7] 梁波文 [8] 车东 Lucene学习笔记(Lucene结构及其简单使用) 2006年 北京航空航天出版社 [9] 朱志文 Lucene1.4.3 试用手记 2004年 人民邮电出版社 [10] 张博 基于Lucene的文件检索 2005年 中国铁道出版社 [11] 马向东 Lucene搜索引擎技术的分析与整理 2006年 电子工业出版社 [12] Exkel著,侯捷译,《Java编程思想(第二版)》,机械工业出版社(北京),2002, ISBN-7-111-10441-2 [13]董慧,丁波涛,余传明.网络信息资源开发与利用[M].武汉:武汉大学出版 社,2001:320-334. [14]Sun Tieli,Zhao Wei,Zhao Zhiyan.An archite engine[J].ACM,2004,14(16):171-174. [15]许天亮,王义峰,曾平.个性化元搜索引擎技术研究[J].电子科技,2008,1(2):56-59. [16]郭琰.元搜索引擎的关键技术研究及系统实现[D].武汉:华中科技大学,2001. [17]黄国景.元搜索引擎个性化搜索的研究与设计[D].苏州:苏州大学计算机学院,2005. [18]KaWaiLam,Chi Ho Leung.Rank aggregation for metasearch Engines[J].ACM,2004,17(22):384-385. [19李娅.个性化智能元搜索引擎模型研究[D].成都:西南大学计算机学院,2006 [20李晓红,冯志勇,张亮.元搜索引擎的个性化[J].天津大学学报,2008,41(5):616-620. [21]闫俊英,辜碧容.元搜索引擎及其关键技术[J].福建电脑,2007,1(11),38-54. 35
/
本文档为【[IT&#47;计算机]基于Lucene的桌面搜索引擎】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索