摘 要: 介紹了將開(kāi)源的全文檢索工具包Lucene嵌入到自己的搜索引" title="索引">索引" title="索引">索引擎中來(lái)滿足開(kāi)發(fā)主題搜索引擎的需求,。并基于Lucene中文分詞的不足設(shè)計(jì)了一個(gè)比較完善的中文分詞器,然后將其引入具體應(yīng)用中,,并且與傳統(tǒng)搜索引擎在性能上進(jìn)行了比較,。
關(guān)鍵詞: Lucene;全文檢索技術(shù),;主題搜索引擎,;索引;中文分詞
國(guó)際互聯(lián)網(wǎng)的迅速發(fā)展使得以Internet為載體的中文電子信息愈來(lái)愈多,,傳統(tǒng)搜索引擎采集索引查詢(xún)內(nèi)容不斷擴(kuò)大,,這不但使搜索引擎面臨巨大的困難,而且越來(lái)越不能滿足主題用戶(hù)的需求,。例如,,為了獲取數(shù)條相關(guān)信息,用戶(hù)不得不在大量的失效信息,、甚至垃圾信息中費(fèi)力尋找,。目前人們對(duì)搜索引擎的首要關(guān)注點(diǎn)已經(jīng)從如何找到更多的信息轉(zhuǎn)向如何快速找到準(zhǔn)確、有用的信息,。因此,,人們希望在企業(yè)應(yīng)用中或者個(gè)人產(chǎn)品中加入自己的搜索功能。這樣不僅可以對(duì)企業(yè)發(fā)布的信息建立索引,,也可以對(duì)企業(yè)計(jì)算機(jī)內(nèi)長(zhǎng)期積累的電子文檔資料建立索引,,實(shí)現(xiàn)方便快速查找。
在Lucene API的基礎(chǔ)上開(kāi)發(fā)面向主題的搜索引擎[1]是一種有效,、低成本的選擇,,因?yàn)長(zhǎng)ucene全文數(shù)據(jù)庫(kù)采用倒排文件索引技術(shù)[2],,所以查詢(xún)速度優(yōu)于關(guān)系型數(shù)據(jù)庫(kù),而且可以免費(fèi)下載,?;贚ucene的優(yōu)勢(shì)已有很多企業(yè)將其應(yīng)用到自己的搜索引擎中,如Eclipse開(kāi)發(fā)環(huán)境的內(nèi)部搜索引擎就是用Lucene構(gòu)建的,。但由于Lucene自帶的中文分詞只能將中文切成單字不能實(shí)現(xiàn)詞語(yǔ)的切分,,因此,符合需求的中文分詞器有待人們?nèi)ラ_(kāi)發(fā),,并將其加入中文分詞模塊來(lái)實(shí)現(xiàn)更高效的檢索,。
1 全文檢索引擎Lucene
1.1 Lucene簡(jiǎn)介
Lucene是apache軟件基金會(huì)jakarta項(xiàng)目組的一個(gè)子項(xiàng)目[3],是一個(gè)開(kāi)放源代碼的全文檢索引擎工具包,,它不是一個(gè)完整的全文檢索引擎,,而是一個(gè)全文檢索引擎的架構(gòu),提供了完整的查詢(xún)引擎和索引引擎,,它為數(shù)據(jù)訪問(wèn)和管理提供了簡(jiǎn)單的函數(shù)調(diào)用接口,,可以方便地嵌入到各種應(yīng)用中,實(shí)現(xiàn)針對(duì)應(yīng)用的全文索引/檢索功能,。
Lucene的API接口設(shè)計(jì)得可以通用,,輸入輸出結(jié)構(gòu)都很像數(shù)據(jù)庫(kù)的表?圯記錄?圯字段,所以很多傳統(tǒng)的應(yīng)用文件,、數(shù)據(jù)庫(kù)等都可以方便地映射到Lucene的存儲(chǔ)結(jié)構(gòu)/接口中,。總體上看,,可以先把Lucene當(dāng)成一個(gè)支持全文索引的數(shù)據(jù)庫(kù)系統(tǒng),。
1.2 Lucene系統(tǒng)結(jié)構(gòu)
Lucene系統(tǒng)結(jié)構(gòu)[2]如圖1所示。從圖1中可以看到,,Lucene的系統(tǒng)由基礎(chǔ)結(jié)構(gòu)封裝,、索引核心、對(duì)外接口三大部分組成,。其中,直接操作索引文件的索引核心又是系統(tǒng)的重點(diǎn),。Lucene將所有源碼分為7個(gè)模塊(在Java語(yǔ)言中以包來(lái)表示),,各個(gè)模塊所表示的系統(tǒng)部分見(jiàn)圖1。需要說(shuō)明的是:org.apache.lucene.queryPaser是org.apache.lucene.search的語(yǔ)法解析器,,不被系統(tǒng)之外實(shí)際調(diào)用,,因此沒(méi)有當(dāng)作對(duì)外接口看待。從面向?qū)ο蟮挠^點(diǎn)來(lái)考慮,,Lucene應(yīng)用了最基本的一條程序設(shè)計(jì)準(zhǔn)則:引入額外的抽象層以降低耦合性,。首先,,引入對(duì)索引文件的操作org.apache.lucene.store的封裝,然后將索引部分的實(shí)現(xiàn)建立在org.apache.lucene.index之上,,完成對(duì)索引核心的抽象,。在索引核心的基礎(chǔ)上開(kāi)始設(shè)計(jì)對(duì)外的接口org.apache.lucene.search及org.apache.lucene.analysis。
1.3 Lucene程序運(yùn)行機(jī)制
Lucene系統(tǒng)功能強(qiáng)大,,實(shí)現(xiàn)復(fù)雜,,但從根本上主要包括2個(gè)主要功能:(1)建立索引庫(kù)[4],也就是將待索引的純文本內(nèi)容經(jīng)切分詞后索引入庫(kù),;(2)檢索索引庫(kù),,即根據(jù)查詢(xún)條件從索引庫(kù)中找出符合條件的文檔。
在研究建立索引庫(kù)時(shí)首先要知道如圖2所示的Lucene索引機(jī)制的架構(gòu),。
從圖2可以看出,,Lucene索引過(guò)程分為3個(gè)主要操作階段:將數(shù)據(jù)轉(zhuǎn)換成文本;分析文本,;將分析過(guò)的文本保存到索引庫(kù)中,。首先,Lucene使用各種解析器對(duì)各種不同類(lèi)型的文檔進(jìn)行解析,,如對(duì)于HTML文檔,,HTML解析器會(huì)做一些預(yù)處理的工作,過(guò)濾文檔中的HTML標(biāo)簽等,,然后輸出文本內(nèi)容,,接著Lucene的分詞器從文本內(nèi)容中提取出索引項(xiàng)以及相關(guān)信息。
檢索索引庫(kù)的運(yùn)行邏輯如下:
(1)輸入查詢(xún)條件,,如用戶(hù)希望查詢(xún)到含有詞“編程”和“入門(mén)”但不含詞“Java”的記錄,,則輸入條件為“編程+入門(mén)-Java”;查詢(xún)條件輸入搜索器(lucene.search),,搜索器里有1個(gè)查詢(xún)解析器(lucene.queryParser),,搜索器調(diào)用這個(gè)查詢(xún)解析器來(lái)解析查詢(xún)條件。
(2)查詢(xún)條件“編程+入門(mén)-Java”被傳送到查詢(xún)解析器中,,解析器將對(duì)“編程+入門(mén)-Java”進(jìn)行分析,,首先分析器解析字符串的連接符,即加號(hào)和減號(hào),,然后調(diào)用語(yǔ)言解析器(lucene.analysis)對(duì)每個(gè)詞進(jìn)行切詞,,一般英文將按空格來(lái)切詞,最后得到的查詢(xún)條件表示為:“編程”AND“入門(mén)”AND NOT“Java”,。
(3)查詢(xún)器根據(jù)查詢(xún)條件檢索事先已建立好的索引庫(kù),,得到查詢(xún)結(jié)果,并返回結(jié)果集lucene.search.Hits,Hits類(lèi)似于JDBC中的ResultSet,。
2 中文分詞
因?yàn)長(zhǎng)ucene提供的兩個(gè)中文分析器(ChineseAnalyzer和CJKAnalyzer)只能將中文切成單漢字,,這對(duì)于絕大多數(shù)中文用戶(hù)來(lái)說(shuō)很不方便,因此有必要開(kāi)發(fā)適合自己的中文分析器,。本系統(tǒng)基于字符串匹配的分詞技術(shù)實(shí)現(xiàn)了一個(gè)中文分詞器,。它是按照一定的策略將待分析的漢字串與1個(gè)“充分大的”詞庫(kù)中的詞條進(jìn)行匹配。若在詞庫(kù)中找到某個(gè)字符串則匹配成功(識(shí)別出1個(gè)詞),。按照掃描方向的不同,,串匹配分詞方法[5]可以分為正向匹配和逆向匹配;按照不同長(zhǎng)度優(yōu)先匹配的情況,,可以分為最大(最長(zhǎng))匹配和最小(最短)匹配,。本研究使用的方式是采用基于字典的雙向匹配算法,即需要進(jìn)行正向和逆向2次匹配,。傳統(tǒng)的方法都是先進(jìn)行1次正向匹配,,然后再進(jìn)行逆向匹配,每次只有1個(gè)方向在進(jìn)行匹配,,而另1個(gè)方向的匹配過(guò)程需要第1個(gè)結(jié)束后才開(kāi)始,。本文的設(shè)計(jì)方法是把多線程技術(shù)引入到中文分詞程序當(dāng)中[6]。因此可以在正向匹配時(shí),,同時(shí)并發(fā)地執(zhí)行逆向匹配,,提高了運(yùn)行速度和執(zhí)行效率。以下為正向匹配和逆向匹配都將調(diào)用的核心程序:
載入處理完的文本,,以字符數(shù)組的形式存儲(chǔ)起來(lái),。建立2個(gè)方法:(1)查找在文本中出現(xiàn)的詞,并且返回詞的長(zhǎng)度,;(2)用來(lái)統(tǒng)計(jì)詞出現(xiàn)的次數(shù)和控制程序進(jìn)度,。
方法1:public int zhaoCi(char[] ch,int juli,,TreeMap[] tmp),。
ch數(shù)組表示的是文本內(nèi)容,juli是詞的長(zhǎng)度,, TreeMap數(shù)組存儲(chǔ)不同長(zhǎng)度的詞,。
方法2:public synchronized void ciPinTongJi(HashMaphm,char[]ch,,int size,,TreeMap[] tmp)。
方法2是并發(fā)執(zhí)行的,,正反匹配都需要這個(gè)方法,。HashMap存儲(chǔ)字典中詞的第1個(gè)字,,ch數(shù)組表示的是文本內(nèi)容,,size是文件的長(zhǎng)度,,TreeMap是數(shù)組存儲(chǔ)不同長(zhǎng)度的詞,按照2個(gè)字,、3個(gè)字,、多個(gè)字的存儲(chǔ)順序存儲(chǔ); 而且方法2是對(duì)外的接口,,方法2調(diào)用方法1,,并利用方法1返回的結(jié)果得到分詞的結(jié)果和詞頻結(jié)果。當(dāng)從文本讀入1個(gè)字時(shí),,使用contain( )來(lái)判斷HashMap中是否存在這個(gè)字的映射,,如果存在就取得長(zhǎng)度等于字典中最長(zhǎng)詞的一段內(nèi)容,在TreeMap數(shù)組中進(jìn)行查找,,如果在TreeMap中找到對(duì)應(yīng)的映射則對(duì)應(yīng)的鍵值加1,,輸出時(shí)在詞后面加上分割符號(hào)‘\’,然后繼續(xù)重復(fù)前面的步驟,,直到文件結(jié)束,,退出;如果TreeMap中不存在,,那么i+1,,讀取下一個(gè)字,重復(fù)前面的步驟,,直到文件的結(jié)尾,,退出,程序結(jié)束,。
正向匹配程序流程圖如圖3所示,。
3 全文檢索引擎Lucene的應(yīng)用
Lucene本身只是一個(gè)組件,若想讓Lucene真正起作用,,還得在Lucene基礎(chǔ)上進(jìn)行必要的2次開(kāi)發(fā)[7],。下面的方案是對(duì)Lucene的應(yīng)用研究,在本系統(tǒng)實(shí)現(xiàn)過(guò)程中要解決的關(guān)鍵問(wèn)題有:數(shù)據(jù)加工及文本數(shù)據(jù)庫(kù)的實(shí)現(xiàn),;全文數(shù)據(jù)索引,;全文數(shù)據(jù)檢索和結(jié)果處理。
3.1 運(yùn)行環(huán)境
操作系統(tǒng):Windows NT/2000/xp,;開(kāi)發(fā)語(yǔ)言:Java,、JSP;開(kāi)發(fā)環(huán)境:MyEclipse6.5,;API插件:Lucene2.3.2(Jakarta Lucene是一套免費(fèi)的開(kāi)放源代碼,,由 Apache Jakarta開(kāi)發(fā));Web服務(wù)器:Apache的Tomcat6.0。
Lucene在Java環(huán)境下運(yùn)行,,因此首先要安裝jdk并設(shè)置環(huán)境變量JAVA_HOME,,還要安裝tomcat6.0。到Lucene的官方網(wǎng)站http://jakarta.apache.org/Lucene/下載1份拷貝(筆者下載的是最新版2.3.2),,下載后將得到一個(gè)名為lucene-2.3.2.zip和apache-ant-1.7.0-bin.zip的壓縮文件,,將其解壓即可。
3.2 系統(tǒng)結(jié)構(gòu)
該應(yīng)用分為3部分:(1)數(shù)據(jù)庫(kù)發(fā)布平臺(tái),,包括服務(wù)器,、Java環(huán)境、Lucene API,、中文分詞模塊,;(2)HTML文件倒排檔生成系統(tǒng);(3)服務(wù)器端執(zhí)行的JSP程序和用戶(hù)界面,。系統(tǒng)結(jié)構(gòu)如圖4所示,。
3.3 Lucene的擴(kuò)展
對(duì)于Lucene組件包,為了能夠支持中文,,要進(jìn)行修改,。首先將改寫(xiě)后支持中文的分析包IKAnalyzer.jar加入到發(fā)布包Analysis包中。解開(kāi)Lucene.zip,,在解開(kāi)的目錄src\demo\org\apache\Lucene\demo下打開(kāi)IndexHTML. java,。在第1處“import org. apache. lucene. analysis. standard. StandardAnalyzer;”下面加1行“import org.apache. lucene. analysis. IKAnalyzer,;”,,把第2處“writer=new IndexWriter (index, new StandardAnalyzer (),,create),;”注釋掉,換成“writer=new IndexWriter(index,,new ChineseAnalyzer(),, create);”解開(kāi)Luceneweb. War,,釋放出configuration. jsp和result. jsp以及web. xml,。編輯configuration. Jsp,找到indexLocation變量,,賦值成“/index”(或者用戶(hù)自己建立的索引的目錄名稱(chēng)),;編輯result. Jsp,找到“Analyzer analyzer=new StopAnalyzer(),;”刪除或者注釋掉,,改成“Analyzer analyzer=new org. apache. lucene. analysis. IKAnalyzer(),;”。這樣就擴(kuò)展了Lucene的中文分詞的功能,。
Lucene并沒(méi)有規(guī)定數(shù)據(jù)源的格式,,而只提供了1個(gè)通用的結(jié)構(gòu)(Document對(duì)象)來(lái)接收索引的輸入,因此輸入的數(shù)據(jù)源可以是:數(shù)據(jù)庫(kù),、WORD文檔、PDF文檔,、HTML文檔……,,只要能夠設(shè)計(jì)相應(yīng)的解析轉(zhuǎn)換器將數(shù)據(jù)源構(gòu)造成Docuement對(duì)象即可進(jìn)行索引。本設(shè)計(jì)實(shí)現(xiàn)了doc,、ppt,、xls、pdf,、txt,、xml解析轉(zhuǎn)換器將其文本信息提取出來(lái)。
3.4 搜索性能的比較
經(jīng)過(guò)多次測(cè)試取平均值,,本設(shè)計(jì)在搜索主題信息的平均速度上比Google要快,,雖然數(shù)量上不如Google檢索的多,但在信息符合度上明顯比其強(qiáng),。這樣就已經(jīng)符合主題用戶(hù),,不一定要多只要精而且節(jié)省時(shí)間的需求,這對(duì)于當(dāng)今效率優(yōu)先的市場(chǎng)來(lái)說(shuō)是非常有競(jìng)爭(zhēng)力的,。應(yīng)用Lucene的搜索引擎的檢索速度與計(jì)算機(jī)的配置有關(guān),,配置較好的計(jì)算機(jī)的搜索時(shí)間相對(duì)要少。以檢索關(guān)鍵字編程為例,,Lucene與Google性能比較結(jié)果如表1所示,。
全文檢索引擎Lucene所構(gòu)建的搜索引擎的搜索個(gè)數(shù)是由磁盤(pán)存儲(chǔ)的信息量的多少?zèng)Q定的,搜索時(shí)間除了第1次檢索有點(diǎn)慢,,以后的時(shí)間耗費(fèi)明顯少于通用搜索引擎,。雖然通用搜索引擎提供的信息量大,但是并不是所有的信息都符合用戶(hù)的需求,,用戶(hù)要在大量的信息中篩選有用的信息要花費(fèi)大量的時(shí)間,,可見(jiàn)主題搜索引擎的優(yōu)勢(shì),本設(shè)計(jì)基本符合預(yù)期的結(jié)果,。
本文提出了一種解決中文全文檢索的方法,,嵌入到Lucene中可以應(yīng)用到搜索引擎、中小企業(yè)網(wǎng)站站內(nèi)檢索,、個(gè)人用戶(hù)桌面搜索引擎建立,、特定文檔檢索數(shù)據(jù)庫(kù)建立等,,從而實(shí)現(xiàn)對(duì)目標(biāo)文檔方便地檢索管理,提高檢索效率,。并且通過(guò)對(duì)全文檢索引擎Lucene的研究以及在Lucene API上的擴(kuò)展,,可以開(kāi)發(fā)出多種應(yīng)用程序,如:網(wǎng)站內(nèi)容搜索系統(tǒng),、可檢索的郵件系統(tǒng),、海量文獻(xiàn)數(shù)據(jù)搜索系統(tǒng)。為了開(kāi)發(fā)出性能指標(biāo)更高的搜索引擎可以根據(jù)現(xiàn)有的排序算法或自定義排序算法自行開(kāi)發(fā)結(jié)果排序模塊加入到Lucene中來(lái)進(jìn)行測(cè)試比較,,這些都有待于繼續(xù)研究,。
參考文獻(xiàn)
[1] 聶頌.具有自動(dòng)分類(lèi)功能的主題搜索引擎的研究[D].天津:天津大學(xué),2004:7-9.
[2] 車(chē)東.在應(yīng)用中加入全文檢索功能——基于Java的全文索引引擎Lucene簡(jiǎn)介[EB/OL].http://www.chedong.com/tech/lucene.html.2005-07.
[3] Lucene[EB/OL].2002.http://lucene.apache.org/java/docs/index.html.2002.
[4] 曹元大,,賀海軍.全文檢索字索引技術(shù)的研究與實(shí)現(xiàn)[J].計(jì)算機(jī)工程,,2002.28(6):286-288.
[5] 黃昌寧.中文信息處理中的分詞問(wèn)題[J].語(yǔ)言文字應(yīng)用,1997(1):72-78.
[6] 李志蜀,,李果.中文搜索引擎的原理剖析及開(kāi)發(fā)實(shí)現(xiàn)技術(shù)[J].計(jì)算機(jī)應(yīng)用研究,,2001(11):98-101.
[7] 肖創(chuàng)柏.基于全文檢索技術(shù)的商業(yè)信函處理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用研究,2004(1):150-152.