当前位置:文档之家› 基于Lucene的网站全文搜索的设计与实现.

基于Lucene的网站全文搜索的设计与实现.

科技情报开发与经济文章编号:1005-6033(2005)15-0242-03SCI/TECHINFORMATIONDEVELOPMENT&ECONOMY2005年第15卷第15期收稿日期:2005-06-03基于Lucene的网站全文搜索的设计与实现陈庆伟1,刘军2(1.山西省网络管理中心,山西太原,030001;2.山西省科技情报研究所,山西太原,030001)摘要:Lucene是一个基于Java技术的开放源代码全文索引引擎工具包,它可以方便地嵌入到各种应用中实现针对应用的全文索引/检索功能。

利用Lucene的API可以比较方便地为一个网站提供全文搜索功能。

探讨了如何使用Lucene建造一个通用的Web站点全文搜索工具,并对在构建系统中应注意的若干问题进行了探讨。

关键词:全文搜索;Lucene;Java中图分类号:TP393.07文献标识码:A在构建一个信息类Web站点的时候,站点的全文搜索功能是必备的功能之一。

一般站点的信息内容都存储在各种数据库系统中,并使用数据库提供的检索和查询功能构建网站的搜索功能。

但随着信息的累‘%keyword%’查询构成的数据检索性能将积,使用数据库中的类似like急剧下降,因此,只使用数据库查询进行全文检索并不是一个好的解决它可以方便方案。

Lucene是一个基于Java技术的全文索引引擎工具包,地嵌入到各种应用中实现针对应用的全文索引/检索功能。

例如Lucene可以快速实现一个简单、功能强大的数据全文检索系统。

PDFWordXSLT格式化各种输出TextXML输出XML格式XML中间格式DBLuceneDB1设计目标全文检索系统的主要功能就是为信息资料提供全文索引和查询。

对其他专业格式图1接口的实现示意图于一个以提供信息资料为主要目的网站来说,网站的全文检索系统是必备功能之一。

但对于小型的信息网站来说,购置全文检索系统的代价经‘keyword’查询来代替全文检索常是昂贵的。

如果只使用数据库的Like系统,其性能又往往达不到要求,甚至影响数据库的其他正常使用。

而使也会遇用其他大型搜索引擎的站内搜索(例如google提供的站内搜索)到更新慢、数据不准确、无法控制输出格式等情况。

那么能不能自己实现一个适用的全文搜索引擎呢?答案是肯定的。

这就是利用开放源代码的搜索引擎工具包Lucene来构成自己的全文搜索引擎,它富有弹性的软件架构可以使我们方便地对其功能进行扩充,以快速实现一个通用网站的全文搜索引擎。

这样一个通用的网站搜索引擎可以达到下面的设计目标:其一,为各种类型的原始文档提供一个适当的包装,以方便搜索引擎对其内容进行索引和存储,这些类型包括Database记录、文本文档、Word/Excel文档、PDF文档以及其他专用的格式文档。

其二,提供内容爬行程序以便可以对不同来源的内容进行索引,其Web页面、文件系统等。

主要的数据来源包括数据库表、其三,提供一个统一的中间输出格式以便对检索结果进行不同的处理和显示。

其四,提供相关词检索,方便用户更有效地查询信息。

从原始文档提取这些属性作为索引文档的共同属性。

2.2系统结构根据上面所讨论的系统设计目标,一个通用的网站全文搜索引擎的整个系统由5个大的模块构成:结构如图2所示,文档抽取模块WordXLMPDFTest文档过滤模块中文分词关键字过滤噪音词过滤系统配置管理文档处理流水线文档适配器数据源爬行器标准数据交换层22.1系统实现接口设计从上面的设计目标我们可以看到,系统的数据来源是多样的,同时索引模块全文检索核心引擎多引擎处理模块LuceneAPILuceneAPI查询模块输出模块XML格式数据XSLT引擎其输出形式也是多样的。

这使我们很容易想到使用XML作为数据的中间格式:所有来自数据源爬行程序的数据转化为XML格式的中间数据,这些中间数据进行进一步的格式化,产生更一致的XML数据结构(例如title和subject元素都统一描述为title,作为文档的标题),最后,这些XML数据进入Lucene引擎进行索引;而数据的输出则可以通过对XML数据的不同格式化处理而实现。

接口的实现如图1所示。

其中,右边的文档属性列表是每个索引文档统一的属性,应该尽量LuceneDBLuceneDB图2通用网站全文搜索引擎结构示意图一是多引擎处理模块。

核心引擎的主要工作是管理文档全文索引数242陈庆伟,刘军基于Lucene的网站全文搜索的设计与实现本刊E-mail\bjb@mail.sxinfo.net信息技术据的处理,它由一个多引擎处理模块作为控制的中心,使得引擎可以同时处理多个不同的索引数据库。

二是文档抽取模块。

它由处理不同类型文档的文档适配器和一个数据源爬行管理器组成,它的主要工作根据配置文件定时产生数据源爬行器以遍历整个数据源,并使用相应的文档适配器对文档内容进行抽取。

三是文档处理模块。

它由一系列文档处理程序模块构成,它们可以在配置管理模块的操纵下挂接在文档处理流水线上。

它可以四是输出模块。

它由一些XSLT模块和一个XSLT引擎构成,对核心引擎产生的结果进行不同的格式化处理,以适应不同外围系统的需要。

五是系统配置模块。

它可以管理系统的配置资源,并可以根据配置的变更动态地更新不同的系统参数配置。

果对全文检索做排序,其性能不能得到保证。

而在索引中,除了匹配度score外,唯一能用来排序的就是索引记录的Id,所以一个比较高效实现定制排序的方法是:在索引时让进入Lucene全文的顺序对应着一定规则,比如时间顺序。

而在搜索时,让搜索结果按照索引记录的Id进行排序(或倒排),这样就避免了在Lucene搜索结果外对结果再次进行排序和在搜索过程中访问不在索引中的某个字段值。

这可以通过修改IndexSearcher中的HitCollector方法来实现:scorer.score(newHitCollector(){privatefloatminScore=0.0f;publicfinalvoidcollect(intdoc,floatscore){if(score>0.0f&&(bits==null||bits.get(doc))){//skipdocsnotinbits[0]++;totalHitsif(score>=minScore){//hq.put(newScoreDoc(doc,score));以前使用score排序hq.put(newScoreDoc(doc,(float)1/doc));//现在使用doc的逆排序if(hq.size()>nDocs){//ifhitqueueoverfull();//removelowestinhitqueuehq.pop(ScoreDoc)hq.top()).score;//resetminScoreminScore=(}}}}reader.maxDoc()},3.3索引优化索引一般分两种情况,一种是小批量的索引扩展,一种是大批量的索引重建。

对于一般的信息类网站来说,由于其内容并不多(<10Gb),因此建议定期对所有文档进行大批量的索引重建。

在索引过程中,并不是每次新的文档对象加入进去索引都重新进行并根据一一次索引文件的写入操作。

Lucene先在内存中进行索引操作,定的批量进行文件的写入。

这个批次的间隔越大,文件的写入次数越少,索引速度会但占用内存将增加;反之占用内存少,但文件IO操作频繁,很慢。

在IndexWriter中有一个Merge_Factor参数可以调整文档的批量大小,可以根据具体的系统配置决定该数值的大小。

该数值的缺省值为20,一般来说,在内存允许的情况下,该数值越大索引速度越快。

3.4搜索过程优化根据对数据引擎的使用经验看来:头100条已经可以满足95%以上的模糊检索需求。

Lucene面向全文检索的优化在于首次索引检索后,并不把所有的记录(Document)具体内容读取出来,而起只将所有结果中因此,结匹配度最高的头100条结果的文档Id放到结果缓存中并返回,果集占用的内存空间很少。

如果首批缓存结果数用完后还要读取更后面的结果时Searcher会再次检索并生成一个比上次的搜索缓存大1倍的缓存,并再重新向后抓取结果。

所以,如果构造一个Searcher去检索101个结果,Searcher也需头100条取完后,缓存结果用完,Searcher重新要进行了2次搜索过程:检索再构造一个200条的结果缓存,依此类推。

由于每次Searcher对象消失后,这些缓存也访问不到那了,因此,对于一个访问量比较大的网站来说应该使用另外的缓存技术以减少实际的数据检索技术。

我们建议的缓存技术应实现下面3点要求:其一,对于任意查询,缓存用户的每一次检索结果集合,这个集合最大容纳200条匹配文档,同时根据时间优先的原则保存10min。

实现这一点,基本可以保证某用户对结果集合进行浏览的时候引擎不再重新检索内容。

其二,对于任意查询,缓存结果的时间和检索结果集合的大小相关,结果集合越大,缓存的时间越短。

因为根据我们的统计,对于结果集合过大的检索,用户倾向于使用更多的关键字对数据进行再次检索。

其三,对于热门关键字的检索,建立一个更加长效的缓存(保存24h或直到网站有了新的内容更新)来存储用户的查询,这对于提供某些专业类信息的站点来说可以极大地减少重新检索的次数。

33.1关键点探讨中文分词对于中文来说,全文索引首先要解决一个语言分析的问题,对于拉丁语来说,语句中单词之间是天然通过空格分开的,但中文字词是连续的,如何在这些由连续汉字组成的语句中把一个具有独立意义的词汇切分出来就是一个很大的问题。

从自然语言处理的角度看,切分出来词汇应该是具有自然语言词汇特征的词汇,这样的分词实际上是一种根据词汇表对语句进行切分的方法,即词表分词。

但即使有词汇表,这样的切分仍然是困难的。

最常见的示例是对“中华人民共和国”这个词汇进行切分处理,从自然语言的角度看,这是一个具有独立意义的完整的词汇,但其中的“华人”在汉语中也是一个具有独立意义的词汇。

因此,对于汉字从自然语言概念上的进行切分,如何适当的分词是一个比较复杂的任务。

幸运的是,对于构建一个简单的全文搜索引擎来说,我们还可以使用另外一种简化的处理方式,即采用自动切分算法。

自动分词可以按照单个字符作为索引单元,也可以将单词按照每两个字符构成一个词汇的两元语法方式切分出来。

例如可用以下方法对“全文检索”进行分词:一是一元切分:“全”“文”“检”“索”。

二是两元切分:“全文”“文检”“检索”。

基于自动切分的最大优点是没有词表维护成本,实现简单,缺点是索引准确程度稍低,但对于中小型应用来说,自动切分准确性还是够用的。

基于两元切分后的索引一般大小和源文件差不多,而对于英文和一元切分,索引文件一般只有原文件的30%到50%。

相关主题