企业erp系统有哪些 基于Lucene的Web站点站内全文检索系统的设计与实现
发布时间:2020-03-07 来源: 散文精选 点击:
〔摘要〕设计一个基于开源检索工具包Lucene的Web站点站内全文检索系统,详述系统的设计思路与体系架构,并对中英文分词和添加文档索引等关键技术给出具体代码和实现步骤 ;最后对该系统进行简单的性能测试并与通用搜索引擎的检索结果进行查全率和查准率方面的比较。
〔关键词〕Lucene 全文检索 搜索引擎
〔分类号〕TP393.07
Design and Implementation of a Website Full-text Retrieval System Based on Lucene
Cao Qiang
Library of Center for Chinese and American Studies, Nanjing University, Nanjing210093
〔Abstract〕The paper designs a full-text retrieval system based on Lucene which can be employed in websites, elaborates on the design methods and the structure of the system, and presents major codes of key technologies such as segmentation of Chinese words, adding index to documents, etc. The paper also gives the results of system benchmark testing and comparing with the current universal search engine in aspects of recall and precision ratio.
〔Keywords〕Lucenefull-text retrievalsearch engine
1引言
对于Web站点来说,一个优秀的站内全文检索系统是不可或缺的。通常有两种方法:①使用通用的桌面搜索引擎如Google等提供的站内搜索功能来检索站点内部数据;②开发自己专用的站内全文检索系统。由于通用搜索引擎的索引更新较慢且针对性不强,因而第一种方法的检索结果有可能不全,还容易出现“坏链接”,查全率和查准率都难以保证。所以对于数据更新较快的站点来说,一般采用的是第二种方法。开发自己专用的站内全文检索系统。
目前大多数的web站点都是采用“后台数据库管理系统+前台活动页面”的模式构建,因而对于站内信息的检索,最直接的办法就是采用数据库管理系统自带的查询命令(如:like ‘%keyword%’等)来实现检索功能。但是由于这种模糊查询并非基于索引,而是需要实时地遍历整个数据库纪录中的文本字段进行匹配,因此其效率十分低下。当数据量很大的时候,系统对查询的响应速度会越来越慢以至于让人无法忍受。即使采用数据库索引,但是目前数据库的索引不是为文档的全文检索而设计的,因此其效率仍旧不高。
此外,对于少数未采用动态页面和数据库技术的站点来说,其采用的文档格式,如文本文档、word文档、PDF文档、HTML文档,等等,并不像数据库文档那样具备完整的查询功能。如何对这部分文档实现检索,也是一个难题。
由上所述,如何构建一个效率较高、针对性较强的通用型Web站点全文检索系统,是一个亟待解决的问题。笔者使用开放性的检索平台Lucene进行二次开发,设计了一个全文检索系统,较为圆满地解决了这个问题。
2关于Lucene
2.1Lucene简介
Lucene是一个基于Java的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为应用程序提供索引和搜索功能。Lucene目前是Apache公司的一个开源项目,也是目前最为流行的基于Java的开源全文检索工具包[1]。
Lucene的检索本质上仍属于索引检索,即用空间来换取时间,对需要检索的文件、字符流进行全文索引,在检索的时候对索引进行快速的检索,得到检索位置,这个位置记录检索词出现的文件路径或者某个关键词。
2.2选择Lucene的原因
目前大部分的数据库引擎都是用B树结构来维护索引,索引的更新会导致大量的I/O操作,Lucene在实现中对此稍微有所改进:不是维护一个索引文件,而是在扩展索引时不断创建新的索引文件,然后定期地将这些新的小索引文件合并到原先的大索引中(针对不同的更新策略,批次的大小可以调整),这样在不影响检索的效率的前提下,提高了索引的效率。Lucene的索引结构在概念上仍为传统的倒排索引结构[1]。
另外,相对于其它一些全文检索系统,Lucene还有以下优点:①可以进行增量的索引(Append),可以对于大量数据进行批量索引,并且接口设计用于优化批量索引和小批量的增量索引;②Lucene没有定义具体的数据源,数据类型就是Lucene索引文件格式中用到的全部数据类型,由于他们都以字节为基础定义而来,因此保证了与平台无关,这也是Lucene索引文件格式平台无关的主要原因;③Lucene只提供一个通用的结构(Document对象)来接受索引的输入,因此可以非常灵活的适应各种应用,输入的数据源可以是数据库、Word文档、PDF文档和HTML文档等,只要前端有合适的转换器把数据源转换成相应结构就可以进行数据索引了。
综上所述,Lucene具备开放源代码、跨平台、数据源来源广、索引效率高等特性,很适合于用来构建全文检索系统。
3原理与实现技术
3.1系统结构分析
Lucene有两个主要的服务:索引和搜索。索引和搜索的任务是相互独立的。索引和搜索服务都可用,这样开发人员就可以对他们进行扩展来满足自己的需求。文本索引是Lucene重点构造的一个可搜寻的索引区域。索引是为高性能内容查询而创建的知识库。Lucene提供丰富的API,可以与存储在索引中的信息交互。用户可以简单地指定索引作为文档名称列表和它的摘要,也可以复杂地指定索引作为整个文档存储内容和相关的附加元数据。例如可以按附加的元数据信息排队,这样在查询结果中就可以区分出优先级较高的一些文档。同时,Lucene也支持“AND”、“+”、“OR”、“NOT”和“一”作为布尔运算符的查询。Lucene功能强大,但从根本上说,主要包括两块:一是文本内容经分词后索引入库;二是根据查询条件返回结果。(如图所1示,其中最重要的两个模块是查询分析器和语言分析器。)
要使用Lucene实现中英文混合检索,①需要按词法结构来构建相应的词法分析逻辑,实现Lucene在org.apache.lucene.analysis中定义的接口,为Lucene提供目标系统所使用的语言处理能力。Lucene已经实现了英文和德文的简单词法分析逻辑(按照空格分词,并去除常用的stopword(语法词,如英语中的is,am,are,等等)。在这里,主要需要参考实现的接口在org.apache.lucene.analysis中的Analyzer.java和Tokenizer.java的定义,Lucene提供了很多英文规范的实现样本,也可以作为实现时的参考资料。②按照被索引的文件格式来提供相应的文本分析逻辑,这里是指除词法分析之外的部分,比如HTML文件,通常需要把其中的内容按照所属域分门别类加入索引,这就需要从org.apache.lucene.document中定义的类document继承,定义自己的HTMLDocument类,然后就可以交给org.apache.lucene.index模块来写入索引文件。完成了这两步之后,Lucene全文检索引擎就基本上完备了。
3.2Lucene的中英文分词
由于语言特性(具备自然分隔符),英文分词比较简单。Lucene自带的StopAnalyzer模块,可以去除stopword,而且可以不区分大小写,过滤掉各类标点符号和语法词,足够满足一般检索需要[2]。
对于中文分词,新的Lucene1.9版本也提供了Standard-Analyzer中文分词接口,不过它所采用的是基于单字的一元切分法。这种分词方法虽然简单实用而且不会损失任何索引信息,但同时也会产生许多无用索引,其直接后果就是用户在最初的几个返回页面中很难找到自己的真正需要,而且对无用索引的维护也给系统增加了额外的开销。
所以在中文分词方面,笔者使用了中国科学院开发的ICTCLAS系统。ICTCLAS是一套广受专家好评的汉语分词系统,该系统采用的算法为隐马尔可夫模型,主要功能有中文分词、词性标注、未登录词识别,等等,是目前效率较高的一套中文分词系统。ICTCLAS提供了JAVA接口,可以使用JNI(Java Native Interface)来调用,在兼容性上不存在任何问题[3]。
3.3中英文混合检索的具体实现
在认真研究了Lucene的Analysis包、目前较好的分析器CJKAnalyzer以及ICTCLAS的JAVA接口以后,笔者编写了一个基于双字词二元切分法的中文分析器。开发平台基于JDK和Lucene1.5,使用JAVA语言实现。分析器的关键代码如下:
public final class njuChineseAnalyzer extends Analyzer {
private Set stopwords;
/*构造一个名为stopwords的字符串数列,该数列是自定义stopword(相对于Lucene本身定义的stopword来说)的列表。可以在此列表中扩展English stopwords和Chinese stopwords,只要将指定的stopword加入该数列即可。列表中的词在文档预处理时都会被自动过滤掉*/
public static final String[]STOP_WORDS =
{"a","an","and","are","as", "at", "be", "but", "by",……
"的","是","不",……};
以下是过滤器的主要代码:
public njuChineseAnalyzer(){
stopwords = StopFilter.makeStopSet(STOP_WORDS);}
public njuChineseAnalyzer(String[] stopwords) {
this.stopwords = StopFilter.makeStopSet(stopwords);}
public TokenStream tokenStream(String fieldName, Reader reader) {
try{
ICTCLAS splitWord = new ICTCLAS();/*通过定义好的接口调用ICTCLAS分词模块*/[4]
String inputString = FileIO.readerToString(reader);
String resultString = splitWord.paragraphProcess(inputString);
return new StopFilter(new LowerCaseTokenizer(new StringReader(resultString)), stopwords);
}
catch (IOException e){
System.out.println("转换出错"); //异常处理
return null;}}
经过对样本文档的处理测试,该分析器的分词效果远远好于Lucene自带的一元切分法分词,继承了ICTCLAS的高效率和高准确率。
3.4为文档添加索引
目前的Web站点主要采用ASP+IIS或PHP+Apache的模式搭建,既有动态页面,也包含静态页面,但在索引设计方面二者差别不大。下面以对动态PHP页面进行索引为例,说明如何为文档添加索引。关键代码如下:
import java.io.File; /*调用JAVA系统模块,还包括FileReader、BufferedReader、IOException、Date、DateFormat,使用同样的语句调用*/
import org.apache.lucene.index.IndexWriter;/*调用Lucene模块,还包括Document、Field、DateField,使用同样的语句调用*/
import org.apache.lucene.analysis.njuChineseAnalyzer;//调用3.3所述的分析器模块
文档索引类定义如下:
class PHPDocIndexer
{
public static void main(String[] args throws ClassNotFoundException, IOException)
{
IndexWriter writer = new IndexWriter("/home/nio/indexes-phpdoc",
new NjuChineseAnalyzer(),true); //索引保存目录,必须存在
indexDocs(writer,new File("/home/nio/phpdoc-zh")); //PHP文件保存目录
……}
public static void indexDocs(IndexWriter writer,File file) throws Exception
{
System.out.print("Add file:" + file + " ...."); //添加文件
Document doc = new Document();
doc.add(Field.UnIndexed("file", file.getName()));? //索引文件名
doc.add(Field.UnIndexed("modified",DateFormat.getDateTimeInstance().format(new Date(file.lastModified()))));?//索引最后修改时间
while (line != null) {
content += line; //截取HTML标题<title>
doc.add(Field.Text("title", title)); //索引标题
status = "end";}}
doc.add(Field.Text("content", content.replaceAll("<[^<>]+>", "")));? //索引内容
writer.addDocument(doc); //加入到现有索引中
……}}
结果输出方面,设计了类似于Google的检索输出页面,使用很方便。在Web服务器端加载Lucene之后,就可以提供站内检索服务了。
3.5测试及性能分析
为了测试该搜索引擎的性能,利用www.nuca.省略作为测试站点进行比较测试。该站点是南京市城市建设档案馆的Web站点,不但包含静态网页,还含有大量的动态网页和数据库文档,可以作为测试的样本。采取的方法是同时向Google站内检索和本文构建的站内引擎提交相同的5个查询关键字,将两者返回的搜索结果进行比较分析,其结果如表1所示。
本文构建的站内检索引擎响应速度较快,一般在2秒之内,而Google由于网络因素等原因响应时间较长,达到了5秒。就检索结果来看,对于短关键词,二者的查询结果差别不大,但站内引擎有响应时间上的优势,而且可以顺利拆分Google所不能拆分的中文词;对于长关键词,站内检索引擎的检索结果较之Google,其查全率更高。但是另一方面,其查准率还是不够好,对于关键词的匹配不是很精确,还需要进一步调整分词模块的代码,使其更好的匹配,以期取得更精确的查询结果。
4结语
文章提出了一个适用于Web站点内部信息全文检索的解决方案,在Lucene的中文分词和Web应用方面作了一定的尝试。未来将以此为基础,为搜索引擎增加语义分析模块,提高搜索精度。在对其功能进行进一步扩充之后,本系统可以应用到数据量较大的大中型网站站内信息的检索,较之传统方法效率和准确率都有提高。采用的Lucene开发包属于开放源代码软件,信息安全性较高;采用了成熟的ICTCLAS系统免费版本构建分词模块,为企业网站节省了一笔开支;开发时使用的JAVA语言具有良好的通用性和跨平台性。另外,还可将其应用于个人用户桌面搜索引擎的开发以及特定全文文档检索数据库的构建等方面。
参考文献:
[1]Jakarta Lucene Home Page.[2006-04-30].http://Jakarta.省略/lucene/.
[2]陈士杰,张明杰.基于Lucene的英汉跨语言信息检索.计算机工程,2005(13):62-64
[3]张华平.Chinese lexical analyzer ICTCLAS API manual.[2006-05-12].http://sewm.pku.省略/QA/reference/ICTCLAS/ICTCLAS_ API.htm.
[4]夏 天,樊孝忠,刘林.利用JNI实现ICTCLAS系统的Java调用.计算机应用,2004(12):177-182
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
相关热词搜索:站内 检索系统 站点 基于Lucene的Web站点站内全文检索系统的设计与实现 基于web排课系统的设计与实现 基于web的教学系统设计与实现
热点文章阅读