徐誠皓
摘要:Lucene是一個基于Java 設(shè)計的,高效開源的全文索引引擎工具包。它簡單卻足夠強大,可以嵌入到各種應用中,實現(xiàn)針對全文的索引和多功能檢索。文章介紹分析了Lucene的系統(tǒng)結(jié)構(gòu)和實現(xiàn)機制,開發(fā)實現(xiàn)了一個基于Lucene的Web應用。
關(guān)鍵詞:全文檢索;Lucene;中文分詞;Web實現(xiàn)
中圖分類號:TP311 文獻標識碼:A 文章編號:1009-3044(2018)10-0092-03
Lucene是一個開源全文檢索工具包,它具有優(yōu)異的索引結(jié)構(gòu)和良好的系統(tǒng)架構(gòu),提供了靈活的API函數(shù)接口和可以定制的數(shù)據(jù)存儲結(jié)構(gòu),以實現(xiàn)具體的全文檢索功能。Lucene完全由Java JDK開發(fā)而成,沒有用到任何第三方開發(fā)包,因此,Lucene也具有良好的跨平臺特性。文章對Lucene進行了研究和分析,以此為基礎(chǔ)設(shè)計實現(xiàn)了一個手機信息檢索的Web應用。
1 全文檢索引擎Lucene
1.1 系統(tǒng)結(jié)構(gòu)
由于是基于Java設(shè)計的,Lucene也運用了面向?qū)ο蟮脑O(shè)計思想,定義了一種使不同平臺間能夠兼容共享的索引文件格式,并通過抽象將系統(tǒng)的核心組成部分設(shè)計為抽象類,具體平臺的實現(xiàn)部分設(shè)計為實現(xiàn)類。此外,與平臺相關(guān)的部分例如文件存儲也封裝為類,并通過逐層處理,形成了一個低耦合、高效率、易擴展的檢索引擎系統(tǒng)。
Lucene 由基礎(chǔ)結(jié)構(gòu)封裝、索引核心、對外接口三大部分組成。系統(tǒng)結(jié)構(gòu)圖如圖1 所示。
如圖1所示,Lucene包含七個組成結(jié)構(gòu):
1. org.apache.lucene.analysis:語言分析器,主要用于分詞;
2. org.apache.lucene.document:存儲索引的文檔結(jié)構(gòu),類似oracle中的表結(jié)構(gòu)
3. org.apache.lucene.index:索引管理,主要包括建立,刪除等
4. org.apache.lucene.search:檢索入口,根據(jù)查詢條件,檢索結(jié)果;
5. org.apache.lucene.queryParser:查詢分析器,根據(jù)關(guān)鍵詞及其相互關(guān)系,提供自定義檢索;
6. org.apache.lucene.store:數(shù)據(jù)存儲管理,主要包括底層I/O操作;
7.org.apache.lucene.util:提供一些工具類。
1.2 與關(guān)系型數(shù)據(jù)庫的對比
一般來說,信息可分為結(jié)構(gòu)化信息和非結(jié)構(gòu)化信息。結(jié)構(gòu)化信息指的是具有固定格式和長度的信息;而非結(jié)構(gòu)化信息指的是不定長,無格式的信息?,F(xiàn)實生活中,大部分信息都是非結(jié)構(gòu)化的,比如HTML頁面,電子郵件等。
關(guān)系型數(shù)據(jù)庫,如oracle,它們在處理結(jié)構(gòu)化信息時,有著高效快速的特點。但是在處理非結(jié)構(gòu)化信息時,由于結(jié)構(gòu)模型等原因的限制,往往力不從心。而Lucene就能夠處理這些非結(jié)構(gòu)化信息,它通過將這些文本數(shù)據(jù)解析成中間格式,再進行索引查詢。
1.3 檢索實現(xiàn)機制
Lucene中最基本的概念是索引(index), 文檔(document), 域(field)和項(term)。索引包含了文檔的序列, 文檔是域的序列, 域是項的序列, 項就是字符串。為了使得基于項的搜索更有效率, 索引中項是靜態(tài)存儲的。Lucene的索引屬于索引方式中的反向索引, 反向索引是一種以項為中心來組織文檔的方式,每個索引項指向一個文檔序列,這個序列中的文檔都包含該項。這正是Lucene所采用的反向索引機制。
1.4 中文分詞
分詞是文本挖掘的基礎(chǔ)與關(guān)鍵。由于Lucene自帶的分詞器對英文的分詞效果較好,但對中文的分詞效果并不如意。為了使檢索系統(tǒng)能更好的處理中文信息,本文采用了IKAnalyzer作為分詞器。IKAnalyzer是一個開源的,基于Java開發(fā)的輕量級的中文分詞工具包。它最初以Lucene為應用主體的,3.0版本后獨立于Lucene,同時對Lucene提供優(yōu)化,是結(jié)合詞典分詞和文法分析算法的中文分詞組件。
本文使用的IKAnalyzer2012FF_u1的特性:
采用了特有的“正向迭代最細粒度切分算法“,支持細粒度和智能分詞兩種切分模式;
具有160萬字/秒(3000KB/S)的高速處理能力;
智能分詞模式支持簡單的分詞排歧義處理和數(shù)量詞合并輸出;
采用了多子處理器分析模式,支持:英文字母、數(shù)字、中文詞匯等分詞處理,兼容韓文、日文字符;
優(yōu)化了詞典存儲,內(nèi)存占用更?。?/p>
用戶詞典擴展定義,支持中文,英文,數(shù)字混合詞語
提供針對Lucene全文檢索優(yōu)化的查詢分析器IKQueryParser;
采用歧義分析算法優(yōu)化查詢關(guān)鍵字的搜索排列組合,能極大的提高Lucene檢索的命中率。
2手機信息檢索系統(tǒng)的實現(xiàn)
本系統(tǒng)采用的是 MyEclipse10 + Struts2 + Tomcat6 的開發(fā)環(huán)境。
2.1 構(gòu)建文本庫
圖2的數(shù)據(jù)是從中關(guān)村手機頻道中整理的手機部分信息,包括廠商,型號,處理器,系統(tǒng),內(nèi)存容量,屏幕尺寸,攝像頭最高像素,報價,特點等,組成以TAB分隔的tsv文件。
2.2 創(chuàng)建索引
一般全文檢索有兩個過程,創(chuàng)建索引和搜索索引。由此可見,索引是全文檢索引擎中的關(guān)鍵,只有建立了索引才能進行全文檢索。Lucene采用了Document邏輯文件和Field域來組織各種數(shù)據(jù)源。我們可以把Document邏輯文件想象成一個新聞HTML頁面,把URL,新聞標題,作者,發(fā)布時間,正文等組成部分看做Field域,再根據(jù)屬性配置進行相應的處理,就能建立索引。
索引過程如下:
1)創(chuàng)建IKAnalyzer中文分詞器對象,用來從文本中提取出索引項。
2)用IndexWriter類創(chuàng)建一個索引(index),并在之后能為索引添加文檔(document)。
3)創(chuàng)建Document類的實例,代表我們要索引的文檔,它是由一個或多個域(field)組成。
4)將不同的域加入到文檔中。比如,一篇文檔有多種信息,如題目,作者,修改時間,內(nèi)容等,都可以域用來表示。
5)IndexWriter類對象調(diào)用函數(shù) addDocument 將索引寫到索引文件夾中。
6)提交保存索引文件。
下面是建立索引的關(guān)鍵代碼:
// 創(chuàng)建分詞器
analyzer = new IKAnalyzer(true);
// 根據(jù)指定的路徑創(chuàng)建索引庫,如果路徑不存在就會創(chuàng)建
directory = FSDirectory.open(new File(INDEX_PATH));
// 創(chuàng)建IndexWriter
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_40, analyzer);
indexWriter = new IndexWriter(directory, config);
for (File file : fileList) {
// 讀取文件的內(nèi)容
List
// 創(chuàng)建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建立了功能強大的索引機制為搜索服務(wù)。
搜索過程如下:
1)使用DirectoryReader將磁盤上的文件夾中索引文件信息讀入到內(nèi)存。
2)使用IndexSearcher創(chuàng)建查詢對象,準備進行搜索。
3)創(chuàng)建IKAnalyzer對象用來對查詢語句進行中文詞法分析和語言處理。
4)創(chuàng)建MultiFieldQueryParser對象用來對查詢語句進行語法分析。
5)調(diào)用MultiFieldQueryParser對象的parser方法進行語法分析,形成查詢語法樹,放到Query對象中。
6) 調(diào)用IndexSearcher對象的search方法,對查詢語法樹Query進行搜索,得到查詢結(jié)果。
下面是進行搜索的關(guān)鍵代碼:
//創(chuàng)建索引庫
directory = FSDirectory.open(new File(INDEX_PATH));
//創(chuàng)建分詞器
analyzer = new IKAnalyzer(true);
ireader = DirectoryReader.open(directory);
//創(chuàng)建查詢對象
IndexSearcher isearcher = new IndexSearcher(ireader);
//要查找的關(guān)鍵字字符串數(shù)組
String[] stringQuery= keywords;
//Occur.MUST表示對應字段必須有查詢值, Occur.MUST_NOT 表示對應字段必須沒有查詢值
String[] fields = new String[keywords.length];
Occur[] occ = new Occur[keywords.length];
//生成關(guān)鍵字與字段間的關(guān)系
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);
//返回查到的數(shù)據(jù)
ScoreDoc[] hits = isearcher.search(query, 1000).scoreDocs;
2.4 系統(tǒng)演示
3結(jié)論
Lucene全文檢索機制主要工作在搜索引擎的索引階段和檢索階段。文章對Lucene在這兩個階段的應用做了初步的探討,實現(xiàn)了一個手機信息檢索系統(tǒng)的實例??梢钥闯?,Lucene在搜索引擎領(lǐng)域的應用有很大發(fā)展前景。
參考文獻:
[1] 郎小偉,王申康.基于Lucene的全文檢索系統(tǒng)研究與開發(fā) [J].計算機工程,2006,32(4):94-99.
[2] 管建和,甘劍峰.基于Lucene全文檢索引擎的應用研究與實現(xiàn) [J].計算機工程與設(shè)計,2007,28(2):489-491.
[3] 向暉,郭一平,王亮. 基于Lucene的中文字典分詞模塊的設(shè)計與實現(xiàn)[J].現(xiàn)代圖書情報技術(shù),2006(8):46-50.
[4] 朱小杰.Lucene教程[EB/OL].
[2016-03-15].https://www.cnblogs.com/zhuxiaojie/p/5277219.html#autoid-5-1-0.
[5] 徐寶文,張衛(wèi)豐.搜索引擎與信息獲取技術(shù) [M].北京:清華大學出版社,2003.
[6] 車東. 在應用中加入全文檢索功能—基于Java的全文索引引擎Lucene簡介[EB/OL].
[2009.03.20]http://www.chedong.com/tech/lucene.html.
[7] 李剛,宋偉.征服Ajax+Lucene構(gòu)建搜索引擎 [M].北京:人民郵電出版社, 2006:220-245.
[8] 文振威,秦曉.個性化搜索引擎的研究與設(shè)計[J].計算機工程與設(shè)計,2009,30(2):342-344.