




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Lucene in Action(簡(jiǎn)體中文版)共10部分 第一部分 Lucene核心1. 接觸Lucene 2. 索引 3. 為程序添加搜索4. 分析5. 高極搜索技術(shù)6. 擴(kuò)展搜索第二部分 Lucene應(yīng)用
2、7. 分析常用文檔格式8. 工具和擴(kuò)充9. Lucene其它版本10. 案例學(xué)習(xí) 序章 Lucene開始是做為私有項(xiàng)目。在1997年末,因?yàn)楣ぷ鞑环€(wěn)定,我尋找自己的一些東西來(lái)賣。Java是比較熱門的編程語(yǔ)言,我需要一個(gè)理由來(lái)學(xué)習(xí)它。我已經(jīng)了解如何來(lái)編寫搜索軟件,所以我想我可以通過(guò)用Java寫搜索軟件來(lái)維持生計(jì)。所以我寫了Lucene。幾年以后,在2000年,我意識(shí)到我沒(méi)有銷
3、售天賦。我對(duì)談判許可和合同沒(méi)有任何興趣,并且我也不想雇人開一家公司。我喜歡做軟件,而不是出售它。所以我把Lucene放在SourceForge上,看看是不是開源能讓我繼續(xù)我想做的。有些人馬上開始使用Lucene。大約一年后,在2001年,Apache提出要采納Lucene。Lucene郵件列表中的消息每天都穩(wěn)定地增長(zhǎng)。也有人開始貢獻(xiàn)代碼,大多是圍繞Lucene的邊緣補(bǔ)充:我依然是僅有的理解它的核心的開發(fā)者。盡管如些,Lucene開始成為真正的合作項(xiàng)目?,F(xiàn)在,2004年,Lucene有一群積極的深刻理解其核心的開發(fā)者。我早已不再每天作開發(fā),這個(gè)強(qiáng)有力的工作組在進(jìn)行實(shí)質(zhì)性的增加與改進(jìn)。這些年來(lái),L
4、ucene已經(jīng)翻譯成很多其它的語(yǔ)言包括C+、C#、Perl和Python。在最開始的Java和其它這些語(yǔ)言中,Lucene的應(yīng)用比我預(yù)想的要廣泛地多。它為不同的應(yīng)用(如財(cái)富100公司討論組、商業(yè)Bug跟蹤、Microsoft提供的郵件搜索和100頁(yè)面范圍的Web搜索引擎)提供搜索動(dòng)力。在業(yè)內(nèi),我被介紹為“Lucene人”。很多人告訴我他們?cè)陧?xiàng)目中使用到Lucene。我依然認(rèn)為我只聽(tīng)說(shuō)了使用Lucene的程序的小部分。如果我當(dāng)初只是出售它,Lucene應(yīng)用得不會(huì)這么廣泛。程序開發(fā)人員看來(lái)更喜歡開源。他們?cè)谟袉?wèn)題時(shí)不用聯(lián)系技術(shù)支持而只需查看一下源代碼。如果這還不夠,郵件列表中的免費(fèi)支持比大多商業(yè)支
5、持要好得多。類似Lucene的開源項(xiàng)目使得程序開發(fā)人員更加有效率。Lucene通過(guò)開源已經(jīng)變得比我想象的偉大的多。我見(jiàn)證了它的發(fā)展,是Lucene社區(qū)的努力才使得它如此興旺。Lucene的未來(lái)怎樣?我無(wú)法回答。有了這本書,你現(xiàn)在也是Lucene社區(qū)的一員,現(xiàn)在由您將Lucene帶往新的高地。旅途順利! DOUG CUTTINGLucene和Nutch的作者前言來(lái)自Erik Hatcher在Internet早期我就對(duì)搜索和索引感興趣。我已經(jīng)建立了用majordomo、MUSH(Mail Users Shell)和少量Perl、awk及shell腳本來(lái)管理郵件列表的存儲(chǔ)結(jié)構(gòu)。我實(shí)現(xiàn)了一個(gè)
6、CGI的web接口,允許用戶搜索這個(gè)列表和其它用戶的信息,其內(nèi)部使用了grep。然后相繼出現(xiàn)了Yahoo!、AltaVista和Excite,這些我都經(jīng)常訪問(wèn)。在我有了第一個(gè)兒子Jakob之后,我開始了數(shù)字照片檔案的設(shè)計(jì)。我想開發(fā)一套管理圖片的系統(tǒng),可以給圖片附加元數(shù)據(jù),如關(guān)鍵字、拍攝日期。當(dāng)然用我選擇的尺寸定位圖片是很容易的。在19世紀(jì)90年代末,我構(gòu)建了基于文件系統(tǒng)的原型,使用了Microsoft的技術(shù),包括Microsoft Index Server、Action Server Pages及處理圖片的第三方COM組件。從那時(shí)起,我的職業(yè)生涯都消耗在這些類似的技術(shù)上了。I was able
7、 to cobble together a compelling application in a couple of days of spare-time hacking.我的職業(yè)轉(zhuǎn)向Java技術(shù),并且我越來(lái)越少地利用Microsoft Windows。為了以系統(tǒng)無(wú)關(guān)的方式用Java技術(shù)重新實(shí)現(xiàn)我的個(gè)人照片檔案系統(tǒng)及搜索引擎,我使用了Lucene。Lucene的簡(jiǎn)單易用遠(yuǎn)遠(yuǎn)超過(guò)了我的期望我所期望的其它開源庫(kù)或工具在概念上簡(jiǎn)單,但是卻難以使用。在2001年,Steve Loughran和我開始編寫Java Development with Ant(Manning)。我們采用圖片搜索引擎的思想,
8、并把它推廣為一個(gè)文檔搜索引擎。這個(gè)程序示例在那本Ant書中使用,而且可被定制為圖片搜索引擎。Ant的責(zé)任不僅來(lái)自于簡(jiǎn)單的編譯打包的構(gòu)建過(guò)程,也來(lái)自于定制的任務(wù),我們?cè)跇?gòu)建過(guò)程中使用Lucene創(chuàng)建索引文件。Ant任務(wù)現(xiàn)在生存在Lucene的Sandbox(沙箱)中,將在本書8.4節(jié)描述。Ant已經(jīng)應(yīng)用在我的博客系統(tǒng)中,我稱為BlogScene()。在建立一個(gè)博客實(shí)體之后,我運(yùn)行一個(gè)Ant構(gòu)建過(guò)程,索引新的實(shí)體并將它們上傳到我的服務(wù)器上。我的博客服務(wù)器由一個(gè)Servlet、一些驗(yàn)證模板和一個(gè)Lucene索引組成,允許(rich)查詢,甚至聯(lián)合查詢。與其它博客系統(tǒng)相比,BlogScene在特色和技
9、巧上差很多,但是它的全文檢索能力非常強(qiáng)大。我現(xiàn)在效力于維吉尼亞大學(xué)對(duì)Patacriticism的應(yīng)用研究小組()。我用對(duì)文本分析、索引和搜索的經(jīng)驗(yàn)通過(guò)討論量子力學(xué)與藝術(shù)的關(guān)系來(lái)測(cè)試及拓展我的思路?!霸?shī)人是世界上不被認(rèn)可的最偉大的工程師”。來(lái)自O(shè)tis Gospodnetic我對(duì)信息搜索與管理的興趣和熱情開始于在Middlebury大學(xué)的學(xué)生時(shí)代。那時(shí)候,我發(fā)現(xiàn)了信息的廣大資源,即Web。盡管Web仍然剛開始發(fā)展,但是對(duì)收集、分析、索引和搜索的長(zhǎng)期需求是很明顯的。我開始對(duì)建立來(lái)自Web的信息庫(kù)感到困惑,開始編寫Web爬行器夢(mèng)想有種方法可以對(duì)這些收集的信息進(jìn)行搜索。我認(rèn)為在巨大的未知領(lǐng)域中搜索是殺
10、手級(jí)軟件。有了這種思想以后,我開始了一系列收集和搜索項(xiàng)目。在1995年,和同學(xué)Marshall Levin一起創(chuàng)建了WebPh,一個(gè)用來(lái)收集和找出個(gè)人聯(lián)系信息的開源程序。基本上,這是一個(gè)簡(jiǎn)單的具有Web接口(CGI)的電話本,那時(shí)排在首位的類型。(實(shí)際上,它在19世紀(jì)90年代末的案例學(xué)習(xí)中被引用為一個(gè)示例。)大學(xué)和政府機(jī)構(gòu)是這個(gè)程序的主要用戶,現(xiàn)在還有很多在使用它。在1997年使用我的WebPh,我繼續(xù)創(chuàng)建了Populus,一個(gè)當(dāng)時(shí)很流行的白頁(yè)。盡管技術(shù)(與WebPh類似)很普通,但是Populus有很重的負(fù)擔(dān),并且能夠與WhoWhere、Bigfoot和Infospace等大角色相媲美。在兩
11、個(gè)關(guān)于個(gè)人聯(lián)系信息的項(xiàng)目之后,是該探索新的領(lǐng)域了。我開始了下一個(gè)冒險(xiǎn),Infojump,用來(lái)在網(wǎng)上時(shí)事通訊、雜志、報(bào)紙中選擇高質(zhì)量的信息。我擁有的軟件由大量的Perl模塊和腳本組成,Infojump利用一個(gè)稱作Webinator的Web爬行器和一個(gè)全文搜索的產(chǎn)品叫作Texis。在1998年Infojump提供的服務(wù)很像今天的FindA。盡管WebPh、Populus和Infojump達(dá)到了它們的目的并是功能很完善,但它們都有技術(shù)的局限性。它們?nèi)鄙俚氖且粋€(gè)用反向索引來(lái)支持全文搜索強(qiáng)大的信息搜索庫(kù)。為了不重復(fù)相同的工作,我開始搜尋一個(gè)我認(rèn)為不可能存在的解決方案。在2000年早期,我發(fā)現(xiàn)了Lucen
12、e,我正在尋找的缺少的部分,并且我一下子就喜歡上了它。我在Lucene還在SourceForge的時(shí)候就加入了這個(gè)項(xiàng)目,后來(lái)2002年Lucene轉(zhuǎn)移到Apache軟件基金會(huì)。我對(duì)Lucene的熱愛(ài)是因?yàn)檫@些年來(lái)它已經(jīng)成為我很多思想的核心組件。這些思想中的一個(gè)是Simpy,我最近的一個(gè)項(xiàng)目。Simpy是個(gè)有許多特點(diǎn)的個(gè)性Web服務(wù),可以讓用戶加標(biāo)簽、索引、搜索和共享在網(wǎng)上找到的信息。它主要使用了Lucene,上千條索引,由Doug Cutting的另一個(gè)項(xiàng)目Nutch(見(jiàn)第10章)提供動(dòng)力支持。我對(duì)Lucene的積極參與導(dǎo)致我被邀請(qǐng)與Erik Hatcher共同編寫Lucene in Acti
13、on。Lucene In Action有關(guān)于Lucene最全面的信息。接下來(lái)的10章包含的信息圍繞你使用Lucene創(chuàng)建優(yōu)秀程序所需的所有主題。這是它平坦且輕快的協(xié)作過(guò)程的結(jié)果,就像Lucene社區(qū)一樣。Lucene和Lucene in Action證明了有類似興趣的人們可以完成什么,不管在人生中會(huì)碰到什么情況,都會(huì)積極地為全球知識(shí)的共享做出貢獻(xiàn)。 致謝朋友! 首先并且是最重要的,我們感謝我們的妻子Carole(Erik)和Margaret(Otis),一直支持這本書的寫作。沒(méi)有她們的支持,這本書就不可能出版。Erik感謝他的兩個(gè)兒子,Ethan和Jakob,因?yàn)樗麄兊娜棠?/p>
14、和理解,Erik寫這本書時(shí)沒(méi)有時(shí)間陪他們玩耍。我們真誠(chéng)感謝Doug Cutting。沒(méi)有Doug的貢獻(xiàn),就不可能有Lucene。沒(méi)有其他Lucene的貢獻(xiàn)者,Lucene就會(huì)少很多特征、更多的Bug,Lucene的成長(zhǎng)就會(huì)花更長(zhǎng)的時(shí)間。感謝所有的貢獻(xiàn)者,包括Peter Carlson、Tal Dayan、Scott Ganyo、Eugene Gluzberg、Brian Goetz、Christoph Goller、Mark Harwook、Tim Jones、Daniel Naber、Andrew C. Oliver、Dmitry Serebrennikov、Kelvin Tan和Matt
15、Tucher。同時(shí),我們感謝所有貢獻(xiàn)在第10章的案例的人:Dion Almaer、Michael Cafarella、Bob Carpenter、Karsten Konrad、Terence Parr、Robert Selvaraj、Ralf Steinbach、Holger Stenzhorn和Craig Walls。 本書簡(jiǎn)介 Lucene in Action為使用最好的Java開源搜索引擎的用戶提供所有細(xì)節(jié)、最好的實(shí)踐、警告、技巧。本書假設(shè)讀者熟悉基本的Java編程。Lucene本身是個(gè)Java檔案(JAR)文件并能集成到簡(jiǎn)單的命令行程序和大型企業(yè)級(jí)應(yīng)用程序中。Roa
16、dmap我們?cè)诒緯?部分覆蓋Lucene核心編程接口(API)使你在將Lucene整合到你的程序中時(shí)愿意使用它:n 第1章,接觸Lucene。我們介紹了一些基本的信息搜索術(shù)語(yǔ)和Lucene的主要競(jìng)爭(zhēng)對(duì)手。我們很快地構(gòu)建了一個(gè)你馬上能用或修改以適應(yīng)需要的簡(jiǎn)單索引和搜索程序。這個(gè)示例程序向你打開了探索Lucene其它能力的大門。n 第2章使你熟悉Lucene基本的索引操作。我們描述了索引數(shù)值和日期的不同字段類型和各種技術(shù)。包括調(diào)整
17、索引過(guò)程、優(yōu)化索引以及如何處理線程安全。n 第3章向你介紹基本的搜索,包括Lucene如何根據(jù)查詢來(lái)排列文檔的細(xì)節(jié)。我們討論基礎(chǔ)的查詢類型及它們?nèi)绾瓮ㄟ^(guò)用戶輸入的查詢表達(dá)式創(chuàng)建。n 第4章深入研究Lucene的索引核心,分析過(guò)程。分析器創(chuàng)建塊及單詞、單詞流和單詞過(guò)濾器。我們創(chuàng)建了一些定制的分析器,showcasing synonym injection and metaphone(like soundex) replacemen
18、t.也分析了非英語(yǔ)語(yǔ)言,典型的分析漢字文本的示例。n 第5章講述搜索章節(jié)剩余的。我們描述了一些高級(jí)的搜索特征,包括排序、過(guò)濾及使用詞向量。高級(jí)的查詢類型在此出現(xiàn),包括SpanQuery家族。最后,我們討論了Lucene對(duì)查詢多索引的內(nèi)建支持,并行的及遠(yuǎn)程的。n 第6章超越高級(jí)搜索,向你展示了如何擴(kuò)展Lucene的搜索能力。你將學(xué)到如何定制搜索結(jié)果的排序、擴(kuò)展查詢表達(dá)式分析、實(shí)現(xiàn)Hit收集和調(diào)整查詢性能。第2部分超越Lucene內(nèi)
19、建的工具并向你展示圍繞Lucene可以做什么。n 第7章,我們創(chuàng)建了可重用、可擴(kuò)展的用來(lái)分析Word、HTML、XML、PDF及其它格式文檔的框架。n 第8章包括圍繞Lucene的擴(kuò)展和工具。我們描述了一些Lucene的索引查看和開發(fā)工具以及Lucene沙箱中的好東西。高亮搜索項(xiàng)就是這種你想要的沙箱擴(kuò)展,還有在Ant構(gòu)建過(guò)程中創(chuàng)建索引的其它工具。使用noncore分析器,并使用類似WordNet的索引。n
20、 第9章描述Lucene翻譯成其它各種語(yǔ)言的版本,如C+、C#、Perl和Python。n 第10章將Lucene的技術(shù)細(xì)節(jié)帶到大量?jī)?yōu)秀的案例學(xué)習(xí)中。這些案例由那些創(chuàng)建了以Lucene為核心的有趣的、快速的、可升級(jí)的程序的開發(fā)者提供。誰(shuí)應(yīng)該閱讀本書?在程序中需要強(qiáng)大搜索能力的開發(fā)人員需要閱讀這本書。Lucene in Action也適合于那些對(duì)Lucene或索引和搜索技術(shù)好奇的開發(fā)人員,他們可能不會(huì)馬上就用到它。把Lucene添加到你的工具箱對(duì)以后的項(xiàng)
21、目來(lái)說(shuō)是值得的搜索是個(gè)熱門的話題并且將來(lái)也會(huì)是。這本書主要使用Java版的Lucene(來(lái)自Apache Jakarta),并且大多數(shù)示例使用Java。最適合熟悉Java的讀者。Java經(jīng)驗(yàn)是很有幫助的,然而Lucene已經(jīng)翻譯成很多其它的語(yǔ)言包括C+、C#、Python和Perl。概念、技術(shù)甚至API本身都和Java版Lucene差不多。代碼示例本書的源代碼可以從Manning的網(wǎng)站。代碼的使用說(shuō)明包含在代碼包的README文件。書中出現(xiàn)的大多數(shù)代碼是由我們編寫并包含在代碼包中。某些代碼(尤其是案例代碼)不在我們的代碼包中提供。書中的代碼片斷歸貢獻(xiàn)者所有。同時(shí),我們包含了Lucene代碼庫(kù)的
22、部分代碼,基于Apache軟件許可協(xié)議()。代碼示例不包括package 和import 語(yǔ)句,以節(jié)省空間;具體請(qǐng)參照實(shí)際代碼。為什么是JUnit?我們相信書中的代碼示例應(yīng)該都是高質(zhì)量的。典型的“hello world”例子經(jīng)常幫助讀者測(cè)試他們的環(huán)境。我們使用獨(dú)特的方法來(lái)使用書中的代碼示例。大部分示例是實(shí)際的JUnit測(cè)試用例()。JUnit,是Java單元測(cè)試框架,可以斷言一個(gè)特殊情況是否能以可重復(fù)的方式出現(xiàn)。通過(guò)IDE或Ant進(jìn)行自動(dòng)JUnit測(cè)試用例可以一步一步地構(gòu)筑系統(tǒng)。我們?cè)诒緯檬褂肑Unit是因?yàn)槠綍r(shí)都在其它項(xiàng)目中使用,并想讓你看看我們?nèi)绾尉幋a。測(cè)試驅(qū)動(dòng)開發(fā)(Test Drive
23、n Development, TDD)是我們強(qiáng)烈推薦的開發(fā)模式。如果你對(duì)JUnit不熟,請(qǐng)閱讀以下基礎(chǔ)。我們也建議你閱讀Dave Thomas和Andy Hunt編著的Pragmatic Unit Testing in Java with JUnit,還有Vincent Massol和Ted Husted編著的JUnit in Action。JUnit基礎(chǔ)這部分是對(duì)JUnit快速但當(dāng)然不完整的介紹。我們將提供理解我們示例代碼所需的基礎(chǔ)知識(shí)。首先,我們的JUnit測(cè)試用例繼承junit.framework.TestCase并且很多通過(guò)部LiaTestCase基類間接繼承它。我們的具體測(cè)試類附合這
24、個(gè)命名習(xí)慣:給類名加后綴Test。例如,我們的QueryParser的測(cè)試是QueryParserTest.java。JUnit自動(dòng)執(zhí)行所有類似public void testXXX()的方法,此處XXX是個(gè)任意有意義的名稱。JUnit測(cè)試方法必須簡(jiǎn)潔,保持好的設(shè)計(jì)。(例如創(chuàng)建可重復(fù)的功能模塊等等)斷言JUnit建立在一組assert語(yǔ)句上,使你自由編寫簡(jiǎn)潔的測(cè)試代碼并使JUnit框架處理失敗狀態(tài)及指出細(xì)節(jié)。最常用的assert語(yǔ)句是assertEquals;一些是為不同的數(shù)據(jù)類型而重載的assertEquals方法。一個(gè)示例測(cè)試方法如下:public void testExample() &
25、#160; SomeObject obj = new SomeObject(); assertEqueals(10, obj.someMethod();如果指定的值(在本例中的10)不等于真實(shí)值(本例中是調(diào)用obj的someMethod的返回值),assert方法拋出運(yùn)行時(shí)異常。除了assertEquals,為了方便還有一些其他assert方法。我們也使用assertTrue(expression)、assertFalse(expression)和assertNull(expression)語(yǔ)句。這些測(cè)試分別判斷這個(gè)表達(dá)式是否是tru
26、e、false和null。assert語(yǔ)句有個(gè)接受一個(gè)附加的String參數(shù)的重載表示。String參數(shù)都是用來(lái)匯報(bào)的,在測(cè)試失敗時(shí)向開發(fā)人員指出更多信息。我們使用這個(gè)String消息參數(shù)以更好的描述。通過(guò)以這種風(fēng)格編寫我們的測(cè)試用例,可以從我們構(gòu)建大系統(tǒng)的復(fù)雜中解放出來(lái),而且可以每次只關(guān)注更少的細(xì)節(jié)。利用合適的測(cè)試用例,我們能夠增強(qiáng)信心和靈活性。信心來(lái)自于我們知道代碼的變化如優(yōu)化算法不會(huì)破壞系統(tǒng)的其它部分,因?yàn)槌霈F(xiàn)這種情況的話,自動(dòng)測(cè)試組件能讓我們?cè)谒绊懏a(chǎn)品之前發(fā)現(xiàn)。重構(gòu)是一種改變代碼內(nèi)部結(jié)構(gòu)的藝術(shù)(或者說(shuō)科學(xué)),所以它能夠適應(yīng)變化的需求而又不影響系統(tǒng)的對(duì)外接口。在上下文中的JUnit讓我
27、們看一下到目前為止談?wù)摰腏Unit并把它放到本書的上下文中。JUnit測(cè)試用例繼承于junit.framework.TestCase,且測(cè)試方法都類似public void testXXX()形式。我們的測(cè)試用例之一(第3章)如下:public class BasicSearchingTest extends LiaTestCase public void testTerm() throws Exception IndexSearcher searcher = new I
28、ndexSearcher(directory); Term t = new Term(“subject”, “ant”); Query query = new TermQuery(t); Hits hits = searcher.search(query); as
29、sertEquals(“JDwA”, 1, hits.length();
30、 One hit expected for search for “ant”
31、60; t = new Term(“subject”, “junit”); hits = searcher.search(new TermQuery(t); assertEquals(2, hits.length();
32、; Two hits expected for “junit” searcher.close(); 當(dāng)然,我們將在之后解釋這個(gè)測(cè)試用
33、例中使用的Lucene API。現(xiàn)在我們只關(guān)注JUnit的細(xì)節(jié)。testTerm方法中的directory變量沒(méi)在此類中定義。JUnit提供一個(gè)在執(zhí)行每個(gè)測(cè)試方法之前的初始化鉤子;這個(gè)鉤子是名為public void setUp()的方法。我們的LiaTestCase基類以這種方式實(shí)現(xiàn)setUp:public abstract class LiaTestCase extends TestCase private String indexDir = System.getProperty(“index.dir”); prot
34、ected Directory directory; protected void setUp() throws Exception directory = FSDirectory.getDirectory(indexDir, false); 如果testTerm中的第一個(gè)斷言失敗,我們會(huì)得到一個(gè)異常:junit.framework.AssertionFalsedError: JDwA expected:<1> b
35、ut was:<0> at lia.searching.BasicSearchingTest. testTerm(BasicSearchingTest.java:20)這個(gè)失敗指出我們的測(cè)試數(shù)據(jù)與預(yù)期的結(jié)果不同。測(cè)試Lucene本書中的大部分測(cè)試都是測(cè)試Lucene本身的。實(shí)際上,這是否現(xiàn)實(shí)呢?難道要測(cè)的不是我們自己寫的代碼而是庫(kù)本身?有個(gè)Test Driven Development的姊妹篇是用來(lái)學(xué)習(xí)API的:Test Driven Learning。它為新API寫測(cè)試以了解它是如何工作以及你能從中得到什么時(shí)非常有幫助。這正是我們?cè)?/p>
36、大部分代碼示例中所做的,所以測(cè)試都是測(cè)試Lucene它本身。但是不要把這些為學(xué)習(xí)而做的測(cè)試拋開。保留它們以確保你在升級(jí)到新版的API或因API改變而重構(gòu)時(shí),它們能夠保持真值。模型對(duì)象在一些用例中,我們使用模型對(duì)象來(lái)測(cè)試。模型對(duì)象用來(lái)作為探測(cè)器傳入真實(shí)的業(yè)務(wù)邏輯,以判斷這個(gè)業(yè)務(wù)邏輯是否正常工作。例如,第4章中有個(gè)SynonymEngine接口(4.6節(jié))。使用這個(gè)接口的真實(shí)業(yè)務(wù)邏輯是個(gè)分析器。當(dāng)我們想測(cè)試這個(gè)分析器本身時(shí),SynonymEngine使用什么類型就不重要,我們只想使用一個(gè)定義良好并有可預(yù)見(jiàn)行為的對(duì)象。模型對(duì)象可以使得測(cè)試用例盡可能簡(jiǎn)單,這樣它們每次只測(cè)試系統(tǒng)的一個(gè)方面,在測(cè)試失敗要
37、修正什么錯(cuò)誤時(shí)沒(méi)有糾纏的依賴。使用模型對(duì)象的一個(gè)好處來(lái)自于設(shè)計(jì)的變動(dòng),例如關(guān)系的分離和設(shè)計(jì)使用接口代替直接具體實(shí)現(xiàn)。我們的測(cè)試數(shù)據(jù)為了避免每個(gè)小節(jié)都要用完全不同的數(shù)據(jù),書中大部多都是圍繞一組公共的示例數(shù)據(jù)以提供一致性。這些示例數(shù)據(jù)由書籍詳細(xì)資料組成。表1顯示了這些數(shù)據(jù),你可以參考它來(lái)理解我們的例子。表1 本書中用到的示例數(shù)據(jù)Title / AuthorCategorySubjectA Modern Art of EducationRudoif Steiner/education/pedagogyeducation philosophypsychology practice WaldorfImp
38、erial Secrets of Healthand LogevityBob Flaws/health/alternative/Chinesediet chinese medicine qigong health herbsTao Te Ching 道德經(jīng)Stephen Mitchell/philosophy/easterntaoismGödel, Escher, Bach:an Eternal Golden BraidDouglas Hofstadter/technology/computers/aiartificial intelligence number theory mat
39、hematics musicMindstormsSeymour Papert/technology/computers/programming/eductionchildren computers powerfulideas LOGO eductionJava Development with AntErik Hatcher,Steve Loughran/technology/computers/programmingapache jakarta ant build tooljunit java developmentJUnit in ActionVincent Massol, Ted Hus
40、ted/technology/computers/programmingjunit unit testing mockobjectsLucene in ActionOtis Gospodnetic,Erik Hatcher/technology/computers/programminglucene searchExtreme ProgrammingExplainedKent Beck/technology/computers/programming/methodologyextreme programming agiletest driven developmentmethodologyTa
41、pestry in ActionHoward Lewis-Ship/technology/computers/programmingtapestry web user interfacecomponentsThe Pragmatic ProgrammerDave Thomas, Andy Hunt/technology/computers/programmingpragmatic agile methodologydeveloper tools 除了表中所顯示的數(shù)據(jù)字段,還有ISBN、URL和出版日期。種類和標(biāo)題字段是我們主觀值,但是另一些都是有關(guān)這些書的真實(shí)客觀值。代碼約定和下載列
42、表和正文中的代碼都以等寬字體的形式出現(xiàn)以與普通文本區(qū)分。在正文中Java方法名稱通常都不包含完整聲明。 第一部分Lucene核心本書的前半部分覆蓋了“盒子外的”(嗯,JAR外的)Lucene。你將以整體的觀點(diǎn)接觸Lucene并開發(fā)一個(gè)完整的索引和搜索程序。每個(gè)后續(xù)的章節(jié)系統(tǒng)地深入研究特定的內(nèi)容?!八饕睌?shù)據(jù)和文檔和后來(lái)的對(duì)它們的“搜索”是使用Lucene的第一步。在從索引過(guò)程返回后,“分析”將使你深入理解在使用Lucene索引文本時(shí)發(fā)生了什么。搜索是Lucene真正的亮點(diǎn):本部分以僅使用內(nèi)建特征的“高級(jí)搜索”技術(shù)結(jié)束,“擴(kuò)展搜索”顯示了Lucene針對(duì)定制目的的擴(kuò)展性。 第一章
43、60;接觸Lucene本章包括 理解Lucene 使用基本的索引API 使用搜索API 考慮可替換產(chǎn)品 Lucene流行和成功的一個(gè)關(guān)鍵因素是它的簡(jiǎn)單。1.1 信息組織和訪問(wèn)的演化1.2 理解Lucene不同的人使用不同的方法解決相同的問(wèn)題即信息超負(fù)荷問(wèn)題。一些人使用新的用戶接
44、口來(lái)工作,一些使用智能代理,還有一些使用發(fā)展較為成熟的搜索工具如Lucene。本章稍后我們展示代碼示例之前,我們將提供給你一張高層次的圖來(lái)說(shuō)明Lucene是什么,它不是什么和它以后會(huì)變得怎樣。1.2.1 Lucene是什么Lucene是一個(gè)高性能、可伸縮的信息搜索(IR)庫(kù)。它使你可以為你的應(yīng)用程序添加索引和搜索能力。Lucene是用java實(shí)現(xiàn)的成熟的、免費(fèi)的開源項(xiàng)目,是著名的Apache Jakarta大家庭的一員,并且基于在Apache軟件許可 ASF, License。同樣,Lucene是當(dāng)前與近幾年內(nèi)非常流行的免費(fèi)的Java信息搜索(IR)庫(kù)。 注意
45、 貫穿這本書,我們將使用術(shù)語(yǔ)IR(Information Retrieval)來(lái)描述像Lucene這樣的搜索工具。人們常常將IR庫(kù)歸諸于搜索引擎,但是一定不要將IR庫(kù)與web搜索引擎混為一談。 正如你馬上就會(huì)發(fā)現(xiàn)的,Lucene提供了一組簡(jiǎn)單卻足夠強(qiáng)大的核心API,只需要最小限度地理解全文索引和搜索。你只須學(xué)習(xí)它的幾個(gè)類從而把Lucene集成到一個(gè)應(yīng)用程序中。因?yàn)長(zhǎng)ucene是一個(gè)Java庫(kù),它并不限定要索引和搜索的內(nèi)容,這使得它比其它一些搜索程序更具有優(yōu)勢(shì)。剛接觸Lucene的人經(jīng)常把它誤解為一個(gè)現(xiàn)成的程序,類似文件搜索程序或web網(wǎng)絡(luò)爬行器或是一個(gè)網(wǎng)站的搜索引擎。那些都不是Luc
46、ene:Lucene是一個(gè)軟件庫(kù),一個(gè)開發(fā)工具包(如果你想這樣稱呼),而不是一個(gè)具有完整特征的搜索應(yīng)用程序。它本身只關(guān)注文本的索引和搜索,并且這些事它完成的非常好。Lucene使得你的應(yīng)用程序只針對(duì)它的問(wèn)題域來(lái)處理業(yè)務(wù)規(guī)則,而把復(fù)雜的索引和搜索實(shí)現(xiàn)隱藏在一組簡(jiǎn)單易用的API之后。你可以把Lucene認(rèn)為成一層,應(yīng)用程序位于它之上,如圖1.5所示。 圖1.5 一個(gè)集成Lucene的典型應(yīng)用 大量基于Lucene的完整的搜索程序已經(jīng)構(gòu)建出來(lái)。如果你正在尋找預(yù)創(chuàng)建的東西或是一個(gè)抓取、文檔處理和搜索的框架,請(qǐng)參考Lucene Wiki 的“powered by”頁(yè)()以獲得更多選擇
47、:Zilverling、SearchBlox、Nutch、LARM和jSearch,還有其它一部分的命名。Nutch和SearchBlox的案例研究包含在第10章。1.2.2 Lucene能做什么Lucene使你可以為你的應(yīng)用程序添加索引和搜索能力(這些功能將在1.3節(jié)中描述)。Lucene可以索引并能使得可以轉(zhuǎn)換成文本格式的任何數(shù)據(jù)能夠被搜索。在圖1.5可以看出,Lucene并不關(guān)心數(shù)據(jù)的來(lái)源、格式甚至它的語(yǔ)言,只要你能將它轉(zhuǎn)換為文本。這就意味著你可經(jīng)索引并搜索存放于文件中的數(shù)據(jù):在遠(yuǎn)程服務(wù)器上的web頁(yè)面,存于本地文件系統(tǒng)的文檔,簡(jiǎn)單的文本文件,微軟Word文檔,HTML或PDF文件或任何
48、其它能夠提取出文本信息的格式。同樣,利用Lucene你可以索引存放于數(shù)據(jù)庫(kù)中的數(shù)據(jù),提供給用戶很多數(shù)據(jù)庫(kù)沒(méi)有提供的全文搜索的能力。一旦你集成了Lucene,你的應(yīng)用程序的用戶就能夠像這樣來(lái)搜索:+George +Rice eat pudding, Apple pie +Tiger, animal:monkey AND food:banana等等。利用Lucene,你可以索引和搜索email郵件,郵件列表檔案,即時(shí)聊天記錄,你的Wiki頁(yè)面等等更多。 1.2.3 Lucene的歷史Lucene最初是由Doug Cutting開發(fā)的,在SourceForge的網(wǎng)站上提供下載。在2001年
49、9月做為高質(zhì)量的開源Java產(chǎn)品加入到Apache軟件基金會(huì)的Jakarta家族中。隨著每個(gè)版本的發(fā)布,這個(gè)項(xiàng)目得到明顯的增強(qiáng),也吸線了更多的用戶和開發(fā)人員。2004年7月,Lucene1.4版正式發(fā)布,10月的1.4.2版本做了一次bug修正。表1.1顯示了Lucene的發(fā)布?xì)v史。 表1.1 Lucene的發(fā)布?xì)v史版本發(fā)布日期里程碑0.012000年3月第一個(gè)開源版本(SourceForge)1.02000年10月 1.01b2001年7月最后的SourceForge版本1.22002年6月第一個(gè)Apache Jakarta版本1.32003年12月復(fù)合索引格式,查詢分析
50、器增加,遠(yuǎn)程搜索,token定位,可擴(kuò)展的API1.42004年7月Sorting, span queries, term vectors1.4.12004年8月排序性能的bug修正1.4.22004年10月IndexSearcher optimization and misc. fixes1.4.32004年冬Misc. fixes 注意 Lucene的創(chuàng)建者,Doug Cutting,在信息搜索領(lǐng)域有很強(qiáng)的理論和實(shí)踐經(jīng)驗(yàn)。他發(fā)表過(guò)許多IR主題相關(guān)的研究論文并曾在Excite、Apple和Grand Central等公司工
51、作。最近,考慮到web搜索引擎數(shù)目的減少和這個(gè)領(lǐng)域的潛在壟斷,他創(chuàng)建了Nutch,第一個(gè)開源的萬(wàn)維網(wǎng)搜索引擎(),它用來(lái)處理抓取、索引和搜索數(shù)十億時(shí)常更新的網(wǎng)頁(yè)。毫不奇怪,Lucene是Nutch的核心,10.1節(jié)包括Nutch如何使用Lucene的案例研究。Doug Cutting 仍然是Lucene的后臺(tái)主力,但是自從Lucene加入到Apache Jakarta的庇護(hù)之后,更多的聰明智慧注入進(jìn)來(lái)。在本書寫作時(shí),Lucene的核心工作組有數(shù)個(gè)積極的開發(fā)者,其中兩位就是本書的作者。除了官方的項(xiàng)目開發(fā)人員,Lucene擁有大量積極的技術(shù)用戶群,經(jīng)常貢獻(xiàn)補(bǔ)丁,Bug修復(fù)和新的特征。1.2.4 誰(shuí)
52、在使用Lucene誰(shuí)不使用呢?除了在Lucene Wiki的Powered by Lucene頁(yè)提到的那些組織外,還有大量的知名的跨圖組織正在使用Lucene。它為Eclipse IDE、Encyclopedia Britannica CD-ROM/DVD、FedEx、Mayo Clinic、Hewlett-Packard、New Scientist雜志、Epiphany、MIT的OpenCourseware和Dspace、Akamai的EdgeComputing平臺(tái)等等提供搜索能力。你的名字也將會(huì)出現(xiàn)在這個(gè)列表中。1.2.5 Lucene其它版本:Perl, Python, C+, .NET
53、, Ruby判斷一個(gè)開源軟件是否成功的一種方法是通過(guò)它被改編為其它語(yǔ)言版本的數(shù)量。使用這個(gè)標(biāo)準(zhǔn),Lucene是非常成功的!盡管開始時(shí)Lucene是用Java寫的,Lucene已經(jīng)有很多其它語(yǔ)言的版本了:Perl,Python,C+和.NET,并且一些基礎(chǔ)已經(jīng)用Ruby實(shí)現(xiàn)了。這對(duì)于那些需要訪問(wèn)用不同的語(yǔ)言寫成的應(yīng)用程序所得到的Lucene索引的開發(fā)者來(lái)說(shuō)是個(gè)好消息。在第9章你將了解更多關(guān)于這方面的東西。1.3 索引和搜索所有搜索引擎的核心就是索引的概念:將原始數(shù)據(jù)處理成一個(gè)高效的交差引用的查找結(jié)構(gòu)以便于快速的搜索。讓我們對(duì)索引和搜索過(guò)程做一次快速的高層次的瀏覽。1.3.1 什么是索引,為什么它
54、很重要?想像一下,你需要搜索大量的文件,并且你想找出包含一個(gè)指定的詞或短語(yǔ)的文件。你如何編寫一個(gè)程序來(lái)做到這個(gè)?一個(gè)幼稚的方法是針對(duì)給定的詞或短語(yǔ)順序掃描每個(gè)文件。這個(gè)方法有很多缺點(diǎn),最明顯的就是它不適合于大量的文件或者文件非常巨大的情況。這時(shí)就出現(xiàn)了索引:為了快速搜索大量的文本,你必須首先索引那個(gè)文本然后把它轉(zhuǎn)化為一個(gè)可以讓你快速搜索的格式,除去緩慢的順序地掃描過(guò)程。這個(gè)轉(zhuǎn)化過(guò)程稱為索引,它的輸出稱為一條索引。你可以把索引理解為一個(gè)可以讓你快速隨機(jī)訪問(wèn)存于其內(nèi)部的詞的數(shù)據(jù)結(jié)構(gòu)。它隱含的概念類似于一本書最后的索引,可以讓你快速找到討論指定主題的頁(yè)面。在Lucene中,一個(gè)索引是一個(gè)精心設(shè)計(jì)的數(shù)
55、據(jù)結(jié)構(gòu),在文件系統(tǒng)中存儲(chǔ)為一組索引文件。我們?cè)诟戒汢中詳細(xì)地說(shuō)明了索引文件的結(jié)構(gòu),但是目前你只須認(rèn)為L(zhǎng)ucene的索引是一個(gè)能快速的詞匯查找的工具。1.3.2 什么是搜索?搜索是在一個(gè)索引中查找單詞來(lái)找出它們所出現(xiàn)的文檔的過(guò)程。一個(gè)搜索的質(zhì)量用精確度和召回率來(lái)描述。召回率衡量搜索系統(tǒng)搜索到相關(guān)文檔的能力,精確度衡量系統(tǒng)過(guò)濾不相關(guān)文檔的能力。然而,在考慮搜索時(shí)你必須考慮其它一些因素。我們已經(jīng)提到速度和快速搜索大量文本的能力。支持單個(gè)和多個(gè)詞匯的查詢,短語(yǔ)查詢,通配符,結(jié)果分級(jí)和排序也是很重要的,在輸入這些查詢的時(shí)候也是友好的語(yǔ)法。Lucene強(qiáng)大的軟件庫(kù)提供了大量的搜索特征、bells和whis
56、tles,所以我們不得不把關(guān)于搜索的討論展開為三章(第3、5、6章)。1.4 Lucene實(shí)戰(zhàn):一個(gè)簡(jiǎn)單的程序讓我們來(lái)實(shí)戰(zhàn)Lucene。首先回憶在1.3.1節(jié)描述的索引和搜索文件的問(wèn)題。此外,假設(shè)你要索引和搜索存放于一個(gè)目錄樹中的文件,并不只在一個(gè)目錄中。為了向你展示Lucene的索引和檢索能力,我們將用到兩個(gè)命令行程序:Indexer和Searcher。首先我們將索引一個(gè)包含文本文件的目錄樹,然后我們搜索創(chuàng)建的索引。這個(gè)示例程序?qū)⑹鼓闶煜ucene的API,簡(jiǎn)單易用而功能強(qiáng)大。代碼清單是完整的,現(xiàn)成的命令行程序。如果文件索引/搜索是你要解決的問(wèn)題,那你可復(fù)制一份代碼,用它來(lái)適應(yīng)你的需要。在
57、接下來(lái)的章節(jié)中,我們將更深入的描述Lucene使用中的每個(gè)方面。在我們可以利用Lucene搜索之前,需要?jiǎng)?chuàng)建一個(gè)索引,所以我們開始Indexer程序。1.4.1 創(chuàng)建一個(gè)索引在本節(jié)中,你將看到一個(gè)名為Indexer的類和它的四個(gè)靜態(tài)方法。它們共同遞歸遍歷文件系統(tǒng)目錄并索引所有具有.txt擴(kuò)展名的文件。當(dāng)Indexer執(zhí)行完畢時(shí),為它的后續(xù)Searcher(在1.4.2小節(jié)中介紹)留下一個(gè)創(chuàng)建好的Lucene索引。我們不期望你熟悉例子中用到的幾個(gè)Lucene類和方法,我們馬上就會(huì)解釋它們。在有注釋的代碼列表之后,我們向你展示了如何使用Indexer。如果你感覺(jué)在看到編碼之前學(xué)習(xí)Indexer如何
58、使用很有幫助,直接跳到代碼后面的用法討論部分。使用Indexer來(lái)索引文本文件列表1.1展示了Indexer命令行程序。它用到兩個(gè)參數(shù):n 我們存放Lucene索引的路徑n 包含我們要索引的文本文件的路徑 列表 1.1 Indexer:遍歷文件系統(tǒng)并且索引.txt文件/* * This code was originally written for * Eriks Lucene intro arti
59、cle */public class Indexer public static void main(String args) throws Exception if (args.length != 2) throw new Exception(“Usage: java ” + Indexer.class.getName()
60、60; + “ ”); File indexDir = new File(args0); File dataDir = new File(args1); &
61、#160; long start = new Data().getTime(); int numIndexed = index(indexDir, dataDir); long end = new Date().getTime(); System.out.println(“I
62、ndexing ” + numIndexed + “ files took ” + (end - start) + “ milliseconds”); / open an index and start file directory traversal public static int index(File inde
63、xDir, File dataDir) throws IOException if (!dataDir.exists() | !dataDir.isDirectory() throw new IOException(dataDir
64、60; + “ does not exist or is not a directory”); IndexWriter writer = new IndexWriter(indexDir, 創(chuàng)建Lucene索引
65、160; new StandardAnalyzer(), true); writer.setUseCompoundFile(false); indexDirectory(writer, dataDir); int numIndexed = writer.docCount()
66、; writer.optimize(); writer.close(); return numIndexed; / recursive method that calls itself when it finds a directory &
67、#160; private static void indexDirectory(IndexWriter writer, File dir) throws IOException File files = dir.listFiles(); for (int i = 0; i < files.length; i+)
68、 File f = files; if (f.isDirectory() indexDirectory(writer, f); 遞
69、歸 else if (f.getName().endsWith(“.txt”) indexFile(writer, f);
70、60; / method to actually index file using Lucene private static void indexFile(IndexWriter writer, File f) throws IOException
71、0; if (f.isHidden() | !f.exists() | !f.canRead() return; System.out.println(“Indexing ” + f.getCanonicalPath(); Document doc = new Document(); doc.add(Field.Text(“contents”, new FileReader(f); 索引文件
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 恒潔衛(wèi)浴換新活動(dòng)方案
- 悅納自我電影活動(dòng)方案
- 情人節(jié)活動(dòng)創(chuàng)意活動(dòng)方案
- 情侶水上活動(dòng)方案
- 情感觀察團(tuán)活動(dòng)方案
- 惠州派對(duì)活動(dòng)方案
- 惠民職工比賽活動(dòng)方案
- 愚人節(jié)餐廳銷售活動(dòng)方案
- 感恩于心活動(dòng)方案
- 感恩大會(huì)活動(dòng)方案
- 譯林版(2024)七年級(jí)下冊(cè)英語(yǔ)期末復(fù)習(xí):完形填空+閱讀理解 練習(xí)題(含答案)
- 第5章 相交線與平行線 復(fù)習(xí)課件
- 廣東省廣州各區(qū)2025屆七下英語(yǔ)期末經(jīng)典試題含答案
- 企業(yè)科技論文管理制度
- 山東卷2025年高考?xì)v史真題
- 2025-2030年中國(guó)蝦苗行業(yè)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 肺曲霉菌病治療講課件
- 頂端分生組織穩(wěn)態(tài)調(diào)控-洞察闡釋
- 2025年農(nóng)業(yè)經(jīng)濟(jì)學(xué)考試試題及答案
- 2025至2030年中國(guó)硫化橡膠制避孕套行業(yè)供需態(tài)勢(shì)分析及投資機(jī)會(huì)分析報(bào)告
- 2025-2030年“一帶一路”背景下甘肅省區(qū)域經(jīng)濟(jì)發(fā)展分析及投資前景報(bào)告
評(píng)論
0/150
提交評(píng)論