




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、LUCENE開發(fā)部署指導(dǎo)手冊(cè)昆明南天開發(fā)中心編者:陳俊昆明南天電腦系統(tǒng)有限公司2010年8月南天WebDT部署開發(fā)手冊(cè) PAGE 45昆明南天電腦系統(tǒng)有限公司0871-3318867引言前言編制本手冊(cè)的目的:1描述Lucene用途,使開發(fā)人員依據(jù)本手冊(cè)初步認(rèn)識(shí)Lucene;2描述Lucene的API,使開發(fā)人員可以快速認(rèn)識(shí)并利用Lucene開發(fā)搜索引擎;3描述Lucene和webdt的融合;4. 重點(diǎn)描述Lucene的應(yīng)用,使開發(fā)人員可按照本手冊(cè)的描述開發(fā)。本手冊(cè)面向的讀者:熟悉Java開發(fā),并對(duì)WEBDT軟件的特點(diǎn)(請(qǐng)參閱技術(shù)白皮書)具有初步認(rèn)識(shí)的技術(shù)人員。概述本
2、手冊(cè)首先介紹了Lucene的概念,詳細(xì)描述了簡單快速地將Lucene融入WEBDT運(yùn)行平臺(tái)并進(jìn)行實(shí)際開發(fā)的方法,使技術(shù)人員對(duì)Lucene有一個(gè)概要性的框架認(rèn)識(shí),為下一步開發(fā)工作奠定基礎(chǔ)。LUCENE 簡介什么是LUNCENELucene是一套java API,就如同Servlet是一套API一樣。Lucene不是一個(gè)獨(dú)立的搜索引擎系統(tǒng),但是你可以使用Luncene來開發(fā)搜索引擎系統(tǒng)。這正如Servlet不是網(wǎng)站系統(tǒng)但是你可以用Servlet開發(fā)網(wǎng)站一樣。有人已經(jīng)用Lucene開發(fā)出了獨(dú)立的搜索引擎系統(tǒng),你可以下載,然后不寫一行代碼就是用它。Nutch是最出名的了。Lucene是一個(gè)全文搜索框架
3、,而不是應(yīng)用產(chǎn)品。因此它并不像 或者google Desktop那么拿來就能用,它只是提供了一種工具讓你能實(shí)現(xiàn)這些產(chǎn)品。 LUNCENE能做什么要回答這個(gè)問題,先要了解Lucene的本質(zhì)。實(shí)際上Lucene的功能很單一,說到底,就是你給它若干個(gè)字符串,然后它為你提供一個(gè)全文搜索服務(wù),告訴你你要搜索的關(guān)鍵詞出現(xiàn)在哪里。知道了這個(gè)本質(zhì),你就可以發(fā)揮想象做任何符合這個(gè)條件的事情了。你可以把站內(nèi)新聞都索引了,做個(gè)資料庫;你可以把一個(gè)數(shù)據(jù)庫表的若干個(gè)字段索引起來,那就不用再擔(dān)心因?yàn)椤?like%”而鎖表了;你也可以寫個(gè)自己的搜索引擎 你該不該選擇Lucene 下面給出一些測(cè)試數(shù)據(jù),如果你覺得可以接受,那
4、么可以選擇。 測(cè)試一:250萬記錄,300M左右文本,生成索引380M左右,800線程下平均處理時(shí)間300ms。 測(cè)試二:37000記錄,索引數(shù)據(jù)庫中的兩個(gè)Varchar字段,索引文件2.6M,800線程下平均處理時(shí)間1.5ms。LUCENE 的 概述下載LUCENE進(jìn)入Lucene的主頁:。可以從主頁中單擊“free download”鏈接,從而轉(zhuǎn)入/dyn/closer.cgi/lucen/java/頁面,這是網(wǎng)站為訪問者推薦的最佳鏡像地址,從這里往往可以得到最快的下載速度。單擊頁面中推薦的鏡像地址,進(jìn)入Lucene的下載頁面:/mirrors/lucene/java。從頁面中選擇luce
5、ne-.zip文件,這是Lucene的二進(jìn)制文件。如果要下載其源代碼,則選擇lucene。LUCENE基本概念A(yù)nalyzerAnalyzer是分析器,它的作用是把一個(gè)字符串按某種規(guī)則劃分成一個(gè)個(gè)詞語,并去除其中的無效詞語,這里說的無效詞語是指英文中的“of”、 “the”,中文中的“的”、“地”等詞語,這些詞語在文章中大量出現(xiàn),但是本身不包含什么關(guān)鍵信息,去掉有利于縮小索引文件、提高效率、提高命中率。 分詞的規(guī)則千變?nèi)f化,但目的只有一個(gè):按語義劃分。這點(diǎn)在英文中比較容易實(shí)現(xiàn),因?yàn)橛⑽谋旧砭褪且詥卧~為單位的,已經(jīng)用空格分開;而中文則必須以某種方法將連成一片的句子劃分成一個(gè)個(gè)詞語。具體劃分方法下
6、面再詳細(xì)介紹,這里只需了解分析器的概念即可。 Document用戶提供的源是一條條記錄,它們可以是文本文件、字符串或者數(shù)據(jù)庫表的一條記錄等等。一條記錄經(jīng)過索引之后,就是以一個(gè)Document的形式存儲(chǔ)在索引文件中的。用戶進(jìn)行搜索,也是以Document列表的形式返回。 Field一個(gè)Document可以包含多個(gè)信息域,例如一篇文章可以包含“標(biāo)題”、“正文”、“最后修改時(shí)間”等信息域,這些信息域就是通過Field在Document中存儲(chǔ)的。 Field有兩個(gè)屬性可選:存儲(chǔ)和索引。通過存儲(chǔ)屬性你可以控制是否對(duì)這個(gè)Field進(jìn)行存儲(chǔ);通過索引屬性你可以控制是否對(duì)該Field進(jìn)行索引。這看起來似乎有些
7、廢話,事實(shí)上對(duì)這兩個(gè)屬性的正確組合很重要,下面舉例說明: 還是以剛才的文章為例子,我們需要對(duì)標(biāo)題和正文進(jìn)行全文搜索,所以我們要把索引屬性設(shè)置為真,同時(shí)我們希望能直接從搜索結(jié)果中提取文章標(biāo)題,所以我們把標(biāo)題域的存儲(chǔ)屬性設(shè)置為真,但是由于正文域太大了,我們?yōu)榱丝s小索引文件大小,將正文域的存儲(chǔ)屬性設(shè)置為假,當(dāng)需要時(shí)再直接讀取文件;我們只是希望能從搜索解果中提取最后修改時(shí)間,不需要對(duì)它進(jìn)行搜索,所以我們把最后修改時(shí)間域的存儲(chǔ)屬性設(shè)置為真,索引屬性設(shè)置為假。上面的三個(gè)域涵蓋了兩個(gè)屬性的三種組合,還有一種全為假的沒有用到,事實(shí)上Field不允許你那么設(shè)置,因?yàn)榧炔淮鎯?chǔ)又不索引的域是沒有意義的。 Termt
8、erm是搜索的最小單位,它表示文檔的一個(gè)詞語,term由兩部分組成:它表示的詞語和這個(gè)詞語所出現(xiàn)的field。 Tockentocken是term的一次出現(xiàn),它包含trem文本和相應(yīng)的起止偏移,以及一個(gè)類型字符串。一句話中可以出現(xiàn)多次相同的詞語,它們都用同一個(gè)term表示,但是用不同的tocken,每個(gè)tocken標(biāo)記該詞語出現(xiàn)的地方。 Segment添加索引時(shí)并不是每個(gè)document都馬上添加到同一個(gè)索引文件,它們首先被寫入到不同的小文件,然后再合并成一個(gè)大索引文件,這里每個(gè)小文件都是一個(gè)segment。 Lucene的結(jié)構(gòu)Lucene包括core和sandbox兩部分,其中core是Lu
9、cene穩(wěn)定的核心部分,sandbox包含了一些附加功能,例如highlighter、各種分析器。 Lucene core有七個(gè)包:analysis,document,index,queryParser,search,store,util。 analysis Analysis包含一些內(nèi)建的分析器,例如按空白字符分詞的WhitespaceAnalyzer,添加了stopwrod過濾的StopAnalyzer,最常用的StandardAnalyzer。 document Document包含文檔的數(shù)據(jù)結(jié)構(gòu),例如Document類定義了存儲(chǔ)文檔的數(shù)據(jù)結(jié)構(gòu),F(xiàn)ield類定義了Document的一個(gè)域。
10、 index Index包含了索引的讀寫類,例如對(duì)索引文件的segment進(jìn)行寫、合并、優(yōu)化的IndexWriter類和對(duì)索引進(jìn)行讀取和刪除操作的 IndexReader類,這里要注意的是不要被IndexReader這個(gè)名字誤導(dǎo),以為它是索引文件的讀取類,實(shí)際上刪除索引也是由它完成, IndexWriter只關(guān)心如何將索引寫入一個(gè)個(gè)segment,并將它們合并優(yōu)化;IndexReader則關(guān)注索引文件中各個(gè)文檔的組織形式。 queryParser QueryParser包含了解析查詢語句的類,Lucene的查詢語句和sql語句有點(diǎn)類似,有各種保留字,按照一定的語法可以組成各種查詢。 Lucen
11、e有很多種Query類,它們都繼承自Query,執(zhí)行各種特殊的查詢,QueryParser的作用就是解析查詢語句,按順序調(diào)用各種 Query類查找出結(jié)果。 SearchSearch包含了從索引中搜索結(jié)果的各種類,例如剛才說的各種Query類,包括TermQuery、BooleanQuery等就在這個(gè)包里。 4.6 store Store包含了索引的存儲(chǔ)類,例如Directory定義了索引文件的存儲(chǔ)結(jié)構(gòu),F(xiàn)SDirectory為存儲(chǔ)在文件中的索引,RAMDirectory為存儲(chǔ)在內(nèi)存中的索引,MmapDirectory為使用內(nèi)存映射的索引。 UtilUtil包含一些公共工具類,例如時(shí)間和字符串之
12、間的轉(zhuǎn)換工具。 如何建索引創(chuàng)建Field創(chuàng)建File的方法有很多種,下面是最常用的方法。Field field= new Field(Field 名稱,F(xiàn)ield 內(nèi)容,存儲(chǔ)方式,索引方式);這四個(gè)參數(shù)的含義如下:Field 名稱就是為Field取得名字,類似數(shù)據(jù)表的字段名稱。Field 內(nèi)容就是該Field 的內(nèi)容,類似數(shù)據(jù)表的字段內(nèi)容。存儲(chǔ)方式包括三種:不存儲(chǔ)(Field.Store.NO)、完全存儲(chǔ)(Field.Store.YES)和壓縮存儲(chǔ)()通常,如果不擔(dān)心索引太大的話,可以可以都使用完全存儲(chǔ)的方式。但是,出于對(duì)性能的考慮,索引文件的內(nèi)容是越小越好。因此,如果Field的內(nèi)容很少就采
13、用完全存儲(chǔ)(如標(biāo)題),如果Field的內(nèi)容很多就采用不存儲(chǔ)或壓縮存儲(chǔ)的方式(如正文)。(4)索引方式包括四種:不索引(Field.Store.NO)、索引但不分析(Filed.Index.NO_NORMS)、索引但不分詞(Field.Index.UN_TOKENIZED)、分次并索引(Field.Index. TOKENIZED)。以新聞稿為例,通常我們會(huì)按照標(biāo)題和全文進(jìn)行模糊搜索,這類需要進(jìn)行模糊搜索的字段就用Field.Index. TOKENIZED。通常我們會(huì)按照作者名稱進(jìn)行精確搜索,需要精心精確搜索的字段就用Field.Index.UN_TOKENIZED。對(duì)于那些只需要跟著搜索結(jié)果
14、顯示出來卻不需要按照其內(nèi)容進(jìn)行搜索的字段,使用Field.Index.NO。創(chuàng)建Document創(chuàng)建Document的方法如下:Document doc= new Document();這個(gè)方法用來創(chuàng)建一個(gè)不含任何Field的空Document。如果想把Field添加到Document里面,只需使用add方法。例如doc.add(field);重復(fù)的使用這個(gè)方法,就可以將多個(gè)Field加入到一個(gè)Document里面。創(chuàng)建IndexWriter創(chuàng)建IndexWriter的方法很多,下面是最常用的方法:IndexWriter writer= new IndexWriter(存儲(chǔ)索引的路徑,分析器的
15、實(shí)例);這兩個(gè)參數(shù)的含義如下:(1) 存儲(chǔ)索引的路徑就是索引被存儲(chǔ)在硬盤上的物理路徑。如:c:my等。(2) 分析器的實(shí)例。分析器是用來做詞法分析的,包括英文分析器和中文分析器等。要根據(jù)所要建立索引的文件情況選擇適當(dāng)?shù)姆治銎鳌3S玫挠蠸tandardAnalyzer(標(biāo)準(zhǔn)分析器)、CJKAnaLyzer(二分法分析器)、ChineseAnlyzer(中文分析器)和FrenchAnalyzer(法語分析器)等??梢愿鶕?jù)自己的需要去編寫分析器,從而處理不同的語言文字。通過建立IndexWriter,就把邏輯索引核物理索引聯(lián)系起來了,這樣就可以很方便的建立索引。例如:IndexWriter wrie
16、r=new IndexWriter(“c:/my/index”,new CJKAnalyzer());這是使用二分法分次器來分析字段內(nèi)容,然后建索引建立在C:/gad/index目錄下。使用 new IndexWriter() 方法建立起來的是一個(gè)空索引器,要把Document添加到索引中來,需要使用addDocument方法。例如:writer.addDocument();這類似于我們前面提到過的向Document中添加Field,重復(fù)執(zhí)行這個(gè)操作就可以向一個(gè)IndexWriter中添加多個(gè)Field。最后,在索引創(chuàng)建完成之時(shí),要使用close方法關(guān)閉索引器。例如:writer.close(
17、); 最簡單的能完成索引的代碼片斷Java代碼 IndexWriterwriter=newIndexWriter(“/data/index/”,newStandardAnalyzer(),true); Documentdoc=newDocument(); doc.add(newField(title,Luceneintroduction,Field.Store.YES,Field.Index.TOKENIZED); doc.add(newField(content,Luceneworkswell,Field.Store.YES,Field.Index.TOKENIZED); writer.ad
18、dDocument(doc); writer.optimize(); writer.close();IndexWriter writer = new IndexWriter(“/data/index/”, new StandardAnalyzer(), true);Document doc = new Document();doc.add(new Field(title, lucene introduction, Field.Store.YES, Field.Index.TOKENIZED);doc.add(new Field(content, lucene works well, Field
19、.Store.YES, Field.Index.TOKENIZED);writer.addDocument(doc);writer.optimize();writer.close();下面我們分析一下這段代碼。 首先我們創(chuàng)建了一個(gè)writer,并指定存放索引的目錄為“/data/index”,使用的分析器為StandardAnalyzer,第三個(gè)參數(shù)說明如果已經(jīng)有索引文件在索引目錄下,我們將覆蓋它們。 然后我們新建一個(gè)document。 我們向document添加一個(gè)field,名字是“title”,內(nèi)容是“Lucene introduction”,對(duì)它進(jìn)行存儲(chǔ)并索引。 再添加一個(gè)名字是“co
20、ntent”的field,內(nèi)容是“Lucene works well”,也是存儲(chǔ)并索引。 然后我們將這個(gè)文檔添加到索引中,如果有多個(gè)文檔,可以重復(fù)上面的操作,創(chuàng)建document并添加。 添加完所有document,我們對(duì)索引進(jìn)行優(yōu)化,優(yōu)化主要是將多個(gè)segment合并到一個(gè),有利于提高索引速度。 隨后將writer關(guān)閉,這點(diǎn)很重要。 執(zhí)行搜索索引創(chuàng)建好以后,就可以執(zhí)行搜索了。執(zhí)行搜索的過程就是:將用戶輸入的關(guān)鍵字處理,從而得到搜索結(jié)果。使用Lucene執(zhí)行搜索,首先要?jiǎng)?chuàng)建IndexSearcher對(duì)象,然后要通過Term和Query對(duì)象來封裝用戶輸入的搜索條件,最后將結(jié)果封裝在Hits對(duì)象中
21、,返回給用戶。創(chuàng)建搜索器對(duì)象:IndexSearcher創(chuàng)建IndexSearcher對(duì)象的方法如下:IndexSearcher searcher= new IndexSearcher(索引存放路徑);創(chuàng)建IndexSearcher對(duì)象很容易,創(chuàng)建完成之后,就可以使用它進(jìn)行搜索了。它最常用的方法是search()。使用search 方法將返回一個(gè)結(jié)果集對(duì)象,即Hits。例如:Hits h =searcher.search();搜索執(zhí)行完畢之后,應(yīng)該使用close()方法關(guān)閉IndexSearcher對(duì)象。例如:Searcher.close();封裝搜索條件:使用Term和Query 對(duì)象如果我
22、們要從一個(gè)索引中搜索“title”字段包含“中國”的文檔,該怎么辦?這時(shí),用戶的搜索條件是Field為title,關(guān)鍵詞為“中國”。創(chuàng)建Trem對(duì)象來封裝這個(gè)搜索條件,可用:Term t= new Term(“title”,“中國”);由此可見Term對(duì)象的創(chuàng)建方法,即:Term t=new Term(“字段名稱”,“關(guān)鍵字”);然后,我們要?jiǎng)?chuàng)建一個(gè)Query對(duì)象,從而把Term對(duì)象轉(zhuǎn)化成可執(zhí)行的查詢條件。Query對(duì)象有很多種,我們暫時(shí)只介紹最簡單的TermQuery對(duì)象。用法如下:Query q =new TermQuery(t);至此,用戶的搜索請(qǐng)求就被封裝好了,封裝在Query對(duì)象中。
23、各種各樣的Query下面我們看看Lucene到底允許我們進(jìn)行哪些查詢操作: TermQuery 首先介紹最基本的查詢,如果你想執(zhí)行一個(gè)這樣的查詢:“在content域中包含Lucene的document”,那么你可以用TermQuery: Term t = new Term(content, Lucene; Query query = new TermQuery(t); BooleanQuery 如果你想這么查詢:“在content域中包含java或perl的document”,那么你可以建立兩個(gè)TermQuery并把它們用BooleanQuery連接起來:Java代碼 TermQueryte
24、rmQuery1=newTermQuery(newTerm(content,java); TermQuerytermQuery2=newTermQuery(newTerm(content,perl); BooleanQuerybooleanQuery=newBooleanQuery(); booleanQuery.add(termQuery1,BooleanClause.Occur.SHOULD); booleanQuery.add(termQuery2,BooleanClause.Occur.SHOULD);TermQuery termQuery1 = new TermQuery(new T
25、erm(content, java);TermQuery termQuery 2 = new TermQuery(new Term(content, perl);BooleanQuery booleanQuery = new BooleanQuery();booleanQuery.add(termQuery 1, BooleanClause.Occur.SHOULD);booleanQuery.add(termQuery 2, BooleanClause.Occur.SHOULD);WildcardQuery 如果你想對(duì)某單詞進(jìn)行通配符查詢,你可以用WildcardQuery,通配符包括?匹配
26、一個(gè)任意字符和*匹配零個(gè)或多個(gè)任意字符,例如你搜索use*,你可能找到useful或者useless:Java代碼 Queryquery=newWildcardQuery(newTerm(content,use*);Query query = new WildcardQuery(new Term(content, use*);PhraseQuery 你可能對(duì)中日關(guān)系比較感興趣,想查找中和日挨得比較近(5個(gè)字的距離內(nèi))的文章,超過這個(gè)距離的不予考慮,你可以:Java代碼 PhraseQueryquery=newPhraseQuery(); query.setSlop(5); query.add(
27、newTerm(content,“中”); query.add(newTerm(“content”,“日”);PhraseQuery query = new PhraseQuery();query.setSlop(5);query.add(new Term(content , “中”);query.add(new Term(“content”, “日”);那么它可能搜到“中日合作”、“中方和日方”,但是搜不到“中國某高層領(lǐng)導(dǎo)說日本欠扁”。 PrefixQuery 如果你想搜以中開頭的詞語,你可以用PrefixQuery:Java代碼 PrefixQueryquery=newPrefixQuer
28、y(newTerm(content,中);PrefixQuery query = new PrefixQuery(new Term(content , 中);FuzzyQuery FuzzyQuery用來搜索相似的term,使用Levenshtein算法。假設(shè)你想搜索跟wuzza相似的詞語,你可以:Java代碼 Queryquery=newFuzzyQuery(newTerm(content,wuzza);Query query = new FuzzyQuery(new Term(content, wuzza);你可能得到fuzzy和wuzzy。 RangeQuery 另一個(gè)常用的Query是
29、RangeQuery,你也許想搜索時(shí)間域從20060101到20060130之間的document,你可以用RangeQuery:Java代碼 RangeQueryquery=newRangeQuery(newTerm(“time”,“20060101”),newTerm(“time”,“20060130”),true);RangeQuery query = new RangeQuery(new Term(“time”, “20060101”), new Term(“time”, “20060130”), true);最后的true表示用閉合區(qū)間。QueryParser看了這么多Query,你
30、可能會(huì)問:“不會(huì)讓我自己組合各種Query吧,太麻煩了!”當(dāng)然不會(huì),Lucene提供了一種類似于SQL語句的查詢語句,我們姑且叫它Lucene語句,通過它,你可以把各種查詢一句話搞定,Lucene會(huì)自動(dòng)把它們查分成小塊交給相應(yīng)Query執(zhí)行。下面我們對(duì)應(yīng)每種Query演示一下: TermQuery可以用“field:key”方式,例如“content:Lucene”。 BooleanQuery中與用+,或用 ,例如“content:java contenterl”。 WildcardQuery仍然用?和*,例如“content:use*”。 PhraseQuery用,例如“content:中日
31、5”。 PrefixQuery用*,例如“中*”。 FuzzyQuery用,例如“content: wuzza ”。 RangeQuery用或,前者表示閉區(qū)間,后者表示開區(qū)間,例如“time:20060101 TO 20060130”,注意TO區(qū)分大小寫。 你可以任意組合query string,完成復(fù)雜操作,例如“標(biāo)題或正文包括Lucene,并且時(shí)間在20060101到20060130之間的文章”可以表示為:“+ (title:Lucene content:Lucene) +time:20060101 TO 20060130”。代碼如下:Java代碼 Directorydir=FSDirec
32、tory.getDirectory(PATH,false); IndexSearcheris=newIndexSearcher(dir); QueryParserparser=newQueryParser(content,newStandardAnalyzer(); Queryquery=parser.parse(+(title:Lucenecontent:Lucene)+time:20060101TO20060130; Hitshits=is.search(query); for(inti=0;ihits.length();i+) Documentdoc=hits.doc(i); Syste
33、m.out.println(doc.get(title); is.close();Directory dir = FSDirectory.getDirectory(PATH, false);IndexSearcher is = new IndexSearcher(dir);QueryParser parser = new QueryParser(content, new StandardAnalyzer();Query query = parser.parse(+(title:lucene content:lucene) +time:20060101 TO 20060130;Hits hits
34、 = is.search(query);for (int i = 0; i hits.length(); i+)Document doc = hits.doc(i);System.out.println(doc.get(title);is.close();首先我們創(chuàng)建一個(gè)在指定文件目錄上的IndexSearcher。 然后創(chuàng)建一個(gè)使用StandardAnalyzer作為分析器的QueryParser,它默認(rèn)搜索的域是content。 接著我們用QueryParser來parse查詢字串,生成一個(gè)Query。 然后利用這個(gè)Query去查找結(jié)果,結(jié)果以Hits的形式返回。 這個(gè)Hits對(duì)象包含一個(gè)
35、列表,我們挨個(gè)把它的內(nèi)容顯示出來。 Filterfilter的作用就是限制只查詢索引的某個(gè)子集,它的作用有點(diǎn)像SQL語句里的where,但又有區(qū)別,它不是正規(guī)查詢的一部分,只是對(duì)數(shù)據(jù)源進(jìn)行預(yù)處理,然后交給查詢語句。注意它執(zhí)行的是預(yù)處理,而不是對(duì)查詢結(jié)果進(jìn)行過濾,所以使用filter的代價(jià)是很大的,它可能會(huì)使一次查詢耗時(shí)提高一百倍。 最常用的filter是RangeFilter和QueryFilter。RangeFilter是設(shè)定只搜索指定范圍內(nèi)的索引;QueryFilter是在上次查詢的結(jié)果中搜索。 Filter的使用非常簡單,你只需創(chuàng)建一個(gè)filter實(shí)例,然后把它傳給searcher。繼續(xù)
36、上面的例子,查詢“時(shí)間在20060101到20060130之間的文章”除了將限制寫在query string中,你還可以寫在RangeFilter中:Java代碼 Directorydir=FSDirectory.getDirectory(PATH,false); IndexSearcheris=newIndexSearcher(dir); QueryParserparser=newQueryParser(content,newStandardAnalyzer(); Queryquery=parser.parse(title:Lucenecontent:Lucene; RangeFilterf
37、ilter=newRangeFilter(time,20060101,20060230,true,true); Hitshits=is.search(query,filter); for(inti=0;ihits.length();i+) Documentdoc=hits.doc(i); System.out.println(doc.get(title); is.close();Directory dir = FSDirectory.getDirectory(PATH, false);IndexSearcher is = new IndexSearcher(dir);QueryParser p
38、arser = new QueryParser(content, new StandardAnalyzer();Query query = parser.parse(title:lucene content:lucene;RangeFilter filter = new RangeFilter(time, 20060101, 20060230, true, true);Hits hits = is.search(query, filter);for (int i = 0; i hits.length(); i+)Document doc = hits.doc(i);System.out.pri
39、ntln(doc.get(title);is.close();Sort有時(shí)你想要一個(gè)排好序的結(jié)果集,就像SQL語句的“order by”,Lucene能做到:通過Sort。 Sort sort = new Sort(“time”); /相當(dāng)于SQL的“order by time” Sort sort = new Sort(“time”, true); / 相當(dāng)于SQL的“order by time desc” 下面是一個(gè)完整的例子:Java代碼 Directorydir=FSDirectory.getDirectory(PATH,false); IndexSearcheris=newIndex
40、Searcher(dir); QueryParserparser=newQueryParser(content,newStandardAnalyzer(); Queryquery=parser.parse(title:Lucenecontent:Lucene; RangeFilterfilter=newRangeFilter(time,20060101,20060230,true,true); Sortsort=newSort(“time”); Hitshits=is.search(query,filter,sort); for(inti=0;ihits.length();i+) Docume
41、ntdoc=hits.doc(i); System.out.println(doc.get(title); is.close();執(zhí)行搜索用戶的搜索請(qǐng)求被封裝好了之后,就該把請(qǐng)求傳遞給IndexSearcher對(duì)象,使其執(zhí)行搜索。IndexSearcher對(duì)象調(diào)用search方法,以Query對(duì)象為參數(shù),返回搜索結(jié)果,封裝在Hits對(duì)象中。如下所示:Hits hs=searcher.search(q);提取搜索結(jié)果:了解Hits對(duì)象搜索結(jié)果被封裝在Hits對(duì)象中,要想從中得到結(jié)果的具體內(nèi)容,就需要了解Hits對(duì)象的相關(guān)方法和屬性。我們知道,搜索結(jié)果是由一組Document構(gòu)成的,所以,只要從H
42、its對(duì)象中獲得這些Document,之后就可以從Document中取得Field,進(jìn)而得到原文檔的一切內(nèi)容。Hits對(duì)象有如下常用方法:Document doc(int n) 返回指定序號(hào)的D id(int n) 返回指定序號(hào)的Document的id屬性。int length() 返回Hits對(duì)象的長度,也就是Hits對(duì)象中包含的Document的數(shù)量。float score(int n) 返回指定序號(hào)的Document的score屬性(即文檔得分)。有了這些方法,我們就可以靈活地操作搜索結(jié)果。提取搜索結(jié)果:了解Document對(duì)象在從Hits對(duì)象中提取出Documen
43、t之后,想要獲取這個(gè)Document中含有的具體內(nèi)容時(shí),就要了解他的一些常用方法。Field getField(String name)參數(shù)是Field名稱,返回值是該Field對(duì)象。List getFields()無參數(shù),返回值是List類型,包含該Document的所有Field。Enumeration fields()無參數(shù),返回值是Enumeration類型,包含該Document的所有Field。String get(String name)參數(shù)是Field名稱,返回值是該Field對(duì)象的字符串值。提取搜索結(jié)果:了解Field對(duì)象使用Document對(duì)象的相關(guān)方法獲得Field對(duì)象之
44、后,就可以跳用Field對(duì)象的方法來獲得詳細(xì)信息。Field對(duì)象的常用方法如下:(1)byte binary Vakue()獲得指定Field對(duì)象的二進(jìn)制值。(2)Reader readerValue()獲得指定Field對(duì)象的內(nèi)容,以Reader形式返回。(3)String stringValue()獲得指定Field對(duì)象的字符串值,這個(gè)方法是最常用的。中文分詞分詞的方法 分詞的方法主要有以下幾種:單字切分 單字切分就是把一段文字按照每個(gè)字去建立索引。如果用來切分“我愛你”,就會(huì)切成“我”,“愛”,“你”3個(gè)詞。這種分此法效率低,但也能解決一些問題。(2) 二分法二分法就是把一段文字的每兩個(gè)
45、相鄰的字算做一個(gè)詞。如果用來切分“我愛你”,就切成“我愛”,“愛你”。這種分詞法效率也低,但比單字切分好得多。(3) 詞典法詞典法就是建立一個(gè)詞典文件,然后使用詞典和文字段落進(jìn)行匹配,從而得出分此結(jié)果。在這種分此方法中,詞典和匹配算法是關(guān)鍵。語義法LUCENE的分詞器二分法分詞器 在Lucene軟件包的contrib/analyzers目錄下有一個(gè)lucene-analyzers-.jar文件,其中含有二分法分詞器CJKAnalyzer。只需將此jar放入編譯路徑即可使用CJKAnalyzer。 分詞效果:“我愛你”,切成“我愛”,“愛你”。Lucene自帶的中文分詞器 在Lucene軟件包的
46、contrib/analyzers目錄下有一個(gè)lucene-analyzers-.jar文件,其中含有二分法分詞器ChineseAnalyzer。只需將此jar放入編譯路徑即可使用ChineseAnalyzer,這個(gè)分詞器目前使用的是單字切分。 分詞效果:“我愛你”,切成“我”,“愛”,“你”。NGram分詞器的原理和用法在Lucene軟件包的contrib/analyzers目錄下有一個(gè)lucene-analyzers-.jar文件,其中含有二分法分詞器NGramTokenizer。只需將此jar放入編譯路徑即可使用NGramTokenizer,這個(gè)分詞器目前使用的是單字切分。 分詞效果:“
47、我愛你”,切成“我|愛|你”,“我愛|愛你”,“我|我愛|愛你|你”。JE分詞器的原理和用法 JE分詞器是一個(gè)不錯(cuò)的分詞器,許多人都在使用??梢詮纳厦嫦螺d。最新版(2007-5-31)的JE分詞器是,基于詞庫,可以向詞庫中增加新詞。 將je-analysis-.jar放到編譯路徑中即可使用。 分詞效果:“我愛你”,切成“我|愛你”。除了以上列舉的分詞器之外,網(wǎng)上還有其他一些免費(fèi)的分詞器,大家可以更多的了解。數(shù)據(jù)解析數(shù)據(jù)解析的方法有很多種,這里重點(diǎn)介紹Lius類庫。初識(shí)LiusLius 簡介Lius是一套用于建立索引的java框架,它基于Lucene項(xiàng)目而建。使用Lius框架可以索引Micros
48、oft Word、Microsoft Excel、Microsoft Powerpoint、RTF、PDF、XML、HTML、TXT、OpenOffice套件、Zip文檔、MP3、Vcard、Latex和JavaBean文件。下載Lius Lius的項(xiàng)目主頁是/projects/lius/。頁面上有一個(gè)綠色的下載鏈接,單擊它,可以進(jìn)入Lius的下載列表頁面,我們選擇最新的版本Lius-1.0。使用Lius1.0,需要Java5環(huán)境支持。同時(shí),需要把Lius根目錄下的Lius-1.0.jar和lib目錄下的外部類庫加入到編譯路徑。借助Lius解析普通數(shù)據(jù)解析Word使用Lius解析Word的方法
49、如下面案例所示。程序名稱:LiusWord.java,/ 解析Word文檔public String LiusWord(String filepath) WordIndexer wi = new WordIndexer();File f = new File(filepath);String content = ;try wi.setStreamToIndex(new FileInputStream(f);content = wi.getContent(); catch (Exception e) e.printStackTrace();return content;解析Excel使用Lius
50、解析Excel的方法如下面案例所示。程序名稱:LiusExcel.java/ 解析Excel文檔public String LiusExcel(String filepath) ExcelIndexer ei = new ExcelIndexer();File f = new File(filepath);String content = ;try ei.setStreamToIndex(new FileInputStream(f);content = ei.getContent(); catch (Exception e) e.printStackTrace();return content
51、;解析PDF使用Lius解析PDF的方法如下面案例所示。程序名稱:LiusPDF.java/ 解析PDF文檔public String LiusPDF(String filepath) PdfIndexer pi = new PdfIndexer();File f = new File(filepath);String content = ;try pi.setStreamToIndex(new FileInputStream(f);content = pi.getContent(); catch (Exception e) e.printStackTrace();return content
52、;解析PowerPoint使用Lius解析PPT的方法如下面案例所示。程序名稱:LiusPPT.java/ 解析PPT文檔public String LiusPPT(String filepath) PPTIndexer pi = new PPTIndexer();File f = new File(filepath);String content = ;try pi.setStreamToIndex(new FileInputStream(f);content = pi.getContent(); catch (Exception e) e.printStackTrace();return
53、content;Lius解析PowerPoint文件時(shí)借助POI組件。POI組件不僅支持Excel解析,而且支持Word、PowerPoint等多種文件格式的解析,只是目前解析質(zhì)量差,解析方法復(fù)雜。目前Lius對(duì)PowerPoint文件的解析還不支持中文。如果Lius使用了Jacob組件,然后通過PowerPoint的COM組件操作,就可以獲得完好的解析結(jié)果。因?yàn)槟壳癓ius對(duì)PowerPoint文件的解析還不支持中文在這里我使用的是POI組件,先下載 、poi-sc將它們加入到工程的編譯路徑。不過這兩個(gè)包的加入可能會(huì)與Lius中的poi-final-20040804沖突,沖突見導(dǎo)致java.
54、lang.NoSuchMethodError: org.apache.poi.poifs.filesystem.POIFSFileSystem.getRoot()Lorg/apache/poi/poifs/filesystem/DirectoryEntry;錯(cuò)誤。解析PPT的方法如下:/解析PPT文檔 public static String handlePPT(String filename) StringBuffer content = new StringBuffer(); try File file=new File(filename); if(!file.exists() retur
55、n content.toString(); FileInputStream instream=new FileInputStream(file); SlideShow ppt = new SlideShow(instream); Slide slides = ppt.getSlides(); for(int i=0;islides.length;i+) TextRun t = slidesi.getTextRuns();/為了取得幻燈片的文字內(nèi)容,建立TextRun for(int j=0;jt.length;j+) content.append(tj.getText();/這里會(huì)將文字內(nèi)容加
56、到content中去 content.append(slidesi.getTitle(); catch(Exception e) e.printStackTrace(); return content.toString(); 解析TXT使用Lius解析TXT的方法如下面案例所示。程序名稱:LiusTXT.java/ 解析TXT文檔public static String LiusTXT(String filepath) TXTIndexer ti = new TXTIndexer();File f = new File(filepath);String content = ;try ti.se
57、tStreamToIndex(new FileInputStream(f);content = ti.getContent(); catch (Exception e) e.printStackTrace();return content;解析HTML使用Lius解析HTML的方法有兩個(gè)類:JTidyHtmlIndexer和NekoHtmlIndexer。這兩個(gè)類分別利用了JTidy類庫和Neko類庫。/ 解析HTML文檔1public String LiusJTidy (String filepath) JTidyHtmlIndexer ji = new JTidyHtmlIndexer (
58、);File f = new File(filepath);String content = ;try ji.setStreamToIndex(new FileInputStream(f);content = ji.getContent(); catch (Exception e) e.printStackTrace();return content;/ 解析HTML文檔2public String LiusNeko (String filepath) NekoHtmlIndexer ni = new NekoHtmlIndexer ();File f = new File(filepath)
59、;String content = ;try ni.setStreamToIndex(new FileInputStream(f);content = ni.getContent(); catch (Exception e) e.printStackTrace();return content;關(guān)于文件解析還有很多種方法比如PDF的解析還可以借助PDFBox類庫解析,大家可以在網(wǎng)上查閱,也可參考如LUCENE搜索引擎開發(fā)權(quán)威經(jīng)典于天恩著,等書籍。索引的管理索引的刪除Lucene提供了兩種從索引中刪除document的方法,一種是 void deleteDocument(int docNum)
60、這種方法是根據(jù)document在索引中的編號(hào)來刪除,每個(gè)document加進(jìn)索引后都會(huì)有個(gè)唯一編號(hào),所以根據(jù)編號(hào)刪除是一種精確刪除,但是這個(gè)編號(hào)是索引的內(nèi)部結(jié)構(gòu),一般我們不會(huì)知道某個(gè)文件的編號(hào)到底是幾,所以用處不大。另一種是 void deleteDocuments(Term term) 這種方法實(shí)際上是首先根據(jù)參數(shù)term執(zhí)行一個(gè)搜索操作,然后把搜索到的結(jié)果批量刪除了。我們可以通過這個(gè)方法提供一個(gè)嚴(yán)格的查詢條件,達(dá)到刪除指定document的目的。 下面給出一個(gè)例子:Java代碼 Directorydir=FSDirectory.getDirectory(PATH,false); Index
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 社區(qū)商業(yè)合作項(xiàng)目協(xié)議書
- 智慧物流解決方案合作框架協(xié)議
- 海南省部分學(xué)校2024-2025學(xué)年高三下學(xué)期學(xué)業(yè)水平診斷測(cè)試(三)地理試題(含答案)
- 法律行業(yè)法律咨詢免責(zé)聲明書
- 昆蟲歷險(xiǎn)記觀后感
- 超前鋼管 現(xiàn)場(chǎng)質(zhì)量檢驗(yàn)報(bào)告單
- 智能酒店客房控制系統(tǒng)采購合同
- 貨車駕駛員合同協(xié)議書
- 電子商務(wù)行業(yè)增長趨勢(shì)分析表
- 林地土地承包合同
- 農(nóng)行競(jìng)聘高級(jí)專員述職報(bào)告范本
- 湖北省荊州市英語初一上學(xué)期期末試題與參考答案(2024年)
- 鶴壁海格龍升3萬噸溴系列新材料產(chǎn)品環(huán)評(píng)資料環(huán)境影響
- 2024屆全國新高考英語復(fù)習(xí)-讀后續(xù)寫微寫作
- 顳下頜關(guān)節(jié)疾病(口腔頜面外科學(xué)課件)
- 2025屆福建廈門雙十中學(xué)高一數(shù)學(xué)第一學(xué)期期末經(jīng)典模擬試題含解析
- 中考語文一輪專題復(fù)習(xí):詩歌鑒賞中常見的意象(共32張課件)
- 課件:《中華民族共同體概論》第一講 中華民族共同體基礎(chǔ)理論
- 高中《信息技術(shù)》必修1全冊(cè)知識(shí)點(diǎn)復(fù)習(xí)課件
- 2023年上半年教師資格證《高中數(shù)學(xué)》真題及答案
- 【基于PLC智能照明控制系統(tǒng)設(shè)計(jì)10000字(論文)】
評(píng)論
0/150
提交評(píng)論