基于Lucene的全文检索的研究及实现
2018-06-02徐诚皓
徐诚皓
摘要:Lucene是一个基于Java 设计的,高效开源的全文索引引擎工具包。它简单却足够强大,可以嵌入到各种应用中,实现针对全文的索引和多功能检索。文章介绍分析了Lucene的系统结构和实现机制,开发实现了一个基于Lucene的Web应用。
关键词:全文检索;Lucene;中文分词;Web实现
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2018)10-0092-03
Lucene是一个开源全文检索工具包,它具有优异的索引结构和良好的系统架构,提供了灵活的API函数接口和可以定制的数据存储结构,以实现具体的全文检索功能。Lucene完全由Java JDK开发而成,没有用到任何第三方开发包,因此,Lucene也具有良好的跨平台特性。文章对Lucene进行了研究和分析,以此为基础设计实现了一个手机信息检索的Web应用。
1 全文检索引擎Lucene
1.1 系统结构
由于是基于Java设计的,Lucene也运用了面向对象的设计思想,定义了一种使不同平台间能够兼容共享的索引文件格式,并通过抽象将系统的核心组成部分设计为抽象类,具体平台的实现部分设计为实现类。此外,与平台相关的部分例如文件存储也封装为类,并通过逐层处理,形成了一个低耦合、高效率、易扩展的检索引擎系统。
Lucene 由基础结构封装、索引核心、对外接口三大部分组成。系统结构图如图1 所示。
如图1所示,Lucene包含七个组成结构:
1. org.apache.lucene.analysis:语言分析器,主要用于分词;
2. org.apache.lucene.document:存储索引的文档结构,类似oracle中的表结构
3. org.apache.lucene.index:索引管理,主要包括建立,删除等
4. org.apache.lucene.search:检索入口,根据查询条件,检索结果;
5. org.apache.lucene.queryParser:查询分析器,根据关键词及其相互关系,提供自定义检索;
6. org.apache.lucene.store:数据存储管理,主要包括底层I/O操作;
7.org.apache.lucene.util:提供一些工具类。
1.2 与关系型数据库的对比
一般来说,信息可分为结构化信息和非结构化信息。结构化信息指的是具有固定格式和长度的信息;而非结构化信息指的是不定长,无格式的信息。现实生活中,大部分信息都是非结构化的,比如HTML页面,电子邮件等。
关系型数据库,如oracle,它们在处理结构化信息时,有着高效快速的特点。但是在处理非结构化信息时,由于结构模型等原因的限制,往往力不从心。而Lucene就能够处理这些非结构化信息,它通过将这些文本数据解析成中间格式,再进行索引查询。
1.3 检索实现机制
Lucene中最基本的概念是索引(index), 文档(document), 域(field)和项(term)。索引包含了文档的序列, 文档是域的序列, 域是项的序列, 项就是字符串。为了使得基于项的搜索更有效率, 索引中项是静态存储的。Lucene的索引属于索引方式中的反向索引, 反向索引是一種以项为中心来组织文档的方式,每个索引项指向一个文档序列,这个序列中的文档都包含该项。这正是Lucene所采用的反向索引机制。
1.4 中文分词
分词是文本挖掘的基础与关键。由于Lucene自带的分词器对英文的分词效果较好,但对中文的分词效果并不如意。为了使检索系统能更好的处理中文信息,本文采用了IKAnalyzer作为分词器。IKAnalyzer是一个开源的,基于Java开发的轻量级的中文分词工具包。它最初以Lucene为应用主体的,3.0版本后独立于Lucene,同时对Lucene提供优化,是结合词典分词和文法分析算法的中文分词组件。
本文使用的IKAnalyzer2012FF_u1的特性:
采用了特有的“正向迭代最细粒度切分算法“,支持细粒度和智能分词两种切分模式;
具有160万字/秒(3000KB/S)的高速处理能力;
智能分词模式支持简单的分词排歧义处理和数量词合并输出;
采用了多子处理器分析模式,支持:英文字母、数字、中文词汇等分词处理,兼容韩文、日文字符;
优化了词典存储,内存占用更小;
用户词典扩展定义,支持中文,英文,数字混合词语
提供针对Lucene全文检索优化的查询分析器IKQueryParser;
采用歧义分析算法优化查询关键字的搜索排列组合,能极大的提高Lucene检索的命中率。
2手机信息检索系统的实现
本系统采用的是 MyEclipse10 + Struts2 + Tomcat6 的开发环境。
2.1 构建文本库
图2的数据是从中关村手机频道中整理的手机部分信息,包括厂商,型号,处理器,系统,内存容量,屏幕尺寸,摄像头最高像素,报价,特点等,组成以TAB分隔的tsv文件。
2.2 创建索引
一般全文检索有两个过程,创建索引和搜索索引。由此可见,索引是全文检索引擎中的关键,只有建立了索引才能进行全文检索。Lucene采用了Document逻辑文件和Field域来组织各种数据源。我们可以把Document逻辑文件想象成一个新闻HTML页面,把URL,新闻标题,作者,发布时间,正文等组成部分看做Field域,再根据属性配置进行相应的处理,就能建立索引。
索引过程如下:
1)创建IKAnalyzer中文分词器对象,用来从文本中提取出索引项。
2)用IndexWriter类创建一个索引(index),并在之后能为索引添加文档(document)。
3)创建Document类的实例,代表我们要索引的文档,它是由一个或多个域(field)组成。
4)将不同的域加入到文档中。比如,一篇文档有多种信息,如题目,作者,修改时间,内容等,都可以域用来表示。
5)IndexWriter类对象调用函数 addDocument 将索引写到索引文件夹中。
6)提交保存索引文件。
下面是建立索引的关键代码:
// 创建分词器
analyzer = new IKAnalyzer(true);
// 根据指定的路径创建索引库,如果路径不存在就会创建
directory = FSDirectory.open(new File(INDEX_PATH));
// 创建IndexWriter
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_40, analyzer);
indexWriter = new IndexWriter(directory, config);
for (File file : fileList) {
// 读取文件的内容
List
// 創建Document对象
for (int i = 0; i < content.size(); i++) {
Document document = new Document();
//Store配置field字段是否存储到索引库
//YES:字段存储到索引库中
//No:不存储到索引库中
document.add(new TextField("contents", content.get(i), Store.YES));
// 通过IndexWriter将文档添加到索引中
indexWriter.addDocument(document); }}
// 提交索引
indexWriter.commit();
2.3 搜索索引
Lucene建立了功能强大的索引机制为搜索服务。
搜索过程如下:
1)使用DirectoryReader将磁盘上的文件夹中索引文件信息读入到内存。
2)使用IndexSearcher创建查询对象,准备进行搜索。
3)创建IKAnalyzer对象用来对查询语句进行中文词法分析和语言处理。
4)创建MultiFieldQueryParser对象用来对查询语句进行语法分析。
5)调用MultiFieldQueryParser对象的parser方法进行语法分析,形成查询语法树,放到Query对象中。
6) 调用IndexSearcher对象的search方法,对查询语法树Query进行搜索,得到查询结果。
下面是进行搜索的关键代码:
//创建索引库
directory = FSDirectory.open(new File(INDEX_PATH));
//创建分词器
analyzer = new IKAnalyzer(true);
ireader = DirectoryReader.open(directory);
//创建查询对象
IndexSearcher isearcher = new IndexSearcher(ireader);
//要查找的关键字字符串数组
String[] stringQuery= keywords;
//Occur.MUST表示对应字段必须有查询值, Occur.MUST_NOT 表示对应字段必须没有查询值
String[] fields = new String[keywords.length];
Occur[] occ = new Occur[keywords.length];
//生成关键字与字段间的关系
for (int i = 0; i < fields.length; i++) {
fields[i] = "contents";
occ[i] = Occur.MUST; }
//查找
Query query = MultiFieldQueryParser.parse(Version.LUCENE_40, stringQuery, fields, occ, analyzer);
//返回查到的数据
ScoreDoc[] hits = isearcher.search(query, 1000).scoreDocs;
2.4 系统演示
3结论
Lucene全文检索机制主要工作在搜索引擎的索引阶段和检索阶段。文章对Lucene在这两个阶段的应用做了初步的探讨,实现了一个手机信息检索系统的实例。可以看出,Lucene在搜索引擎领域的应用有很大发展前景。
参考文献:
[1] 郎小伟,王申康.基于Lucene的全文检索系统研究与开发 [J].计算机工程,2006,32(4):94-99.
[2] 管建和,甘剑峰.基于Lucene全文检索引擎的应用研究与实现 [J].计算机工程与设计,2007,28(2):489-491.
[3] 向晖,郭一平,王亮. 基于Lucene的中文字典分词模块的设计与实现[J].现代图书情报技术,2006(8):46-50.
[4] 朱小杰.Lucene教程[EB/OL].
[2016-03-15].https://www.cnblogs.com/zhuxiaojie/p/5277219.html#autoid-5-1-0.
[5] 徐宝文,张卫丰.搜索引擎与信息获取技术 [M].北京:清华大学出版社,2003.
[6] 车东. 在应用中加入全文检索功能—基于Java的全文索引引擎Lucene简介[EB/OL].
[2009.03.20]http://www.chedong.com/tech/lucene.html.
[7] 李刚,宋伟.征服Ajax+Lucene构建搜索引擎 [M].北京:人民邮电出版社, 2006:220-245.
[8] 文振威,秦晓.个性化搜索引擎的研究与设计[J].计算机工程与设计,2009,30(2):342-344.