寫這個東西就是兩個目的,一是讓自己頭腦清醒,一是讓別人把咱的頭腦弄清醒。技術這個東西跟本能一個樣,只要你願意用成就本能的方式去學習技術,誰都可以成就自己。
因為咱不是文科出身,工作了六年,也沒有那些牛逼人士的韌力和魄力,曾經就想着能多寫寫技術博客,但總是沒有堅持下去(深嘆一口氣,你可別像我這樣。。)。前些日子又看了一下《康熙王朝》(陳道明演的),被里面的一句話(一言之虛,百患叢生; 一事之虛,遺害終生。)給擊蒙了,於是重新想着堅持下去。剛好要跟同事分享lucene,那么也就多學,多看,多想,多寫了。
OK,言歸正傳,到底搜索引擎有多神秘?
對我來說,lucene的出現,沒有多少影響,因為當初我還在一個小公司里面糊里糊塗地混日子,而雖然聽說過這個東西,但沒有用過,僅了解了一下。但自從去了那個網絡公司之后,要做搜索系統,我就切實地接觸到了這個開源神器。至少在一定程度上講,讓我覺得Google,百度不是那么神奇的公司了。因為他們就是用超大規模的爬蟲,倒排表,超大規模的緩存和我不知道的超大的things。
小差時刻:作為一個非計算機專業的從業人員,從一定程度上講,個人表示很慚愧。盡管有編程之熱情,但卻沒有徹底地鑽研從業用到的每個組成部分,這實在有點非專業的風格。我想這個浮躁的社會可能會讓很多人變成(編程)這樣,Matrix造就了我們追求成果不管原理的工作方式。(抱怨一下,但這是自我深深的反省。)
看一段lucene官網的示例代碼:
1 import org.apache.lucene.analysis.Analyzer; 2 import org.apache.lucene.analysis.standard.StandardAnalyzer; 3 import org.apache.lucene.document.Document; 4 import org.apache.lucene.document.Field; 5 import org.apache.lucene.document.TextField; 6 import org.apache.lucene.index.DirectoryReader; 7 import org.apache.lucene.index.IndexWriter; 8 import org.apache.lucene.index.IndexWriterConfig; 9 import org.apache.lucene.queryparser.classic.QueryParser; 10 import org.apache.lucene.search.IndexSearcher; 11 import org.apache.lucene.search.Query; 12 import org.apache.lucene.search.ScoreDoc; 13 import org.apache.lucene.store.Directory; 14 import org.apache.lucene.store.RAMDirectory; 15 import org.apache.lucene.util.Version; 16 17 public final class TestLucene { 18 19 public static void main(String[] args) throws Exception{ 20 Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT); 21 22 // Store the index in memory: 23 Directory directory = new RAMDirectory(); 24 // To store an index on disk, use this instead: 25 //Directory directory = FSDirectory.open("/tmp/testindex"); 26 IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer); 27 IndexWriter iwriter = new IndexWriter(directory, config); 28 Document doc = new Document(); 29 String text = "This is the text to be indexed."; 30 doc.add(new Field("fieldname", text, TextField.TYPE_STORED)); 31 iwriter.addDocument(doc); 32 iwriter.close(); 33 34 // Now search the index: 35 DirectoryReader ireader = DirectoryReader.open(directory); 36 IndexSearcher isearcher = new IndexSearcher(ireader); 37 // Parse a simple query that searches for "text": 38 QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "fieldname", analyzer); 39 Query query = parser.parse("text"); 40 ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs; 41 // Iterate through the results: 42 for (int i = 0; i < hits.length; i++) { 43 Document hitDoc = isearcher.doc(hits[i].doc); 44 System.out.println(hitDoc.get("fieldname")); 45 } 46 ireader.close(); 47 directory.close(); 48 } 49 50 }
聲明:以上這段代碼,main里面的代碼都是取自lucene官網的。但也要特別說明一下,在maven pom.xml里面,對於lucene4.0版本的依賴配置如下:
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>4.0.0</version>
</dependency>
好像3.x版本的不需要這么多配置的吧(好像又好久沒跟進lucene測試了。。呵呵)
僅僅從這個demo的import里面,我們能看到lucene的基本功能結構分割:

Lucene是一個文本內容的全文檢索系統,從上圖我們也可以看出lucene的確有比較明確且抽象的架構設計。
IndexWriter:接收業務數據,並將索引好的數據寫入到Store中。IndexWriter在接收數據時,主要依靠封裝了文本內容及其元數據的Document(org.apache.lucene.document,夾縫中引用一下,實在是委屈了Document,它也是具有皇室直系血統的類,非常重要。),它在org.apache.lucene.index包中。index包主要管理索引創建階段用到的各種類,如IndexReader, IndexWriter....(還有很多底層類,不一一列舉,但后面在詳細說明時,會一一分析。)
Store:這是一個相對底層的組織,對應包為org.apache.lucene.store,其主要包含與索引數據文件讀寫管理相關的各種類。
IndexSearcher: 這個是使用Query數據對索引數據進行檢索的類。猜得出來,它在org.apache.lucene.search中。
QueryParser:它也是存在於org.apache.lucene.search中,並且其主要職責是解析用戶的輸入字符串,並返回Query對象,然后供IndexSearcher使用,其對IndexSearcher的重要性跟Docment之於IndexWriter有的一拼。
Analyzer:最后才說到Analyzer,並不是說它不重要,相反它極其重要。Analyzer類主要用戶對文本內容進行分詞處理,而分詞質量的好壞關系到搜索結果的相關度,所以也就有了針對不同文化和語言的各種Analyzer。正如圖中展現的,建立和查詢索引時都要用到它,是居家旅行的必備良葯。
對於網絡用戶來說,他們只需要關心query data(就是他們想搜的關鍵詞或者句子),經過Parser解析成關鍵字的query(queryparser的結果),經由IndexSearcher來查詢Indexed Data,並返回結果。而我們在對目標數據建索引的過程,則是經由IndexWriter來解析和分解處理,然后將解析的結果(這是個big problem)保存成Indexed Data。
這里要區分一下,網絡用戶他們只想查找關心的數據,所以他們輸入:關鍵詞;而我們開發者則有業務數據。這里就是說,在使用lucene時,是否需要想想以下幾個方面:
數據獲取:提供用於接收業務數據的接口,搜索請求處理接口;
lucene封裝:組裝索引Document的接口,返回結果的封裝接口,更重要的是log接口(統計和實驗);
瞻前顧后,咱會從Analyzer,Document,Index,Search and Store幾個方面,給各位分享一下lucene的情況。
一點點來,不着急。。。。。
