天天看點

Lucene 五分鐘教程

更新:下面的代碼使用Lucene 4.0版本!

Lucene大大簡化了在應用中內建全文搜尋的功能。但實際上Lucene十分簡單,我可以在五分鐘之内向你展示如何使用Lucene。

1. 建立索引

為了簡單起見,我們下面為一些字元串建立記憶體索引:

StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_40); Directory index = new RAMDirectory(); IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_40, analyzer); IndexWriter w = new IndexWriter(index, config); addDoc(w, "Lucene in Action", "193398817"); addDoc(w, "Lucene for Dummies", "55320055Z"); addDoc(w, "Managing Gigabytes", "55063554A"); addDoc(w, "The Art of Computer Science", "9900333X"); w.close();

addDoc()方法把文檔(譯者注:這裡的文檔是Lucene中的Document類的執行個體)添加到索引中。

private static void addDoc(IndexWriter w, String title, String isbn) throws IOException {   Document doc = new Document();   doc.add(new TextField("title", title, Field.Store.YES));   doc.add(new StringField("isbn", isbn, Field.Store.YES));   w.addDocument(doc); }

注意,對于需要分詞的内容我們使用TextField,對于像id這樣不需要分詞的内容我們使用StringField。

2.搜尋請求

我們從标準輸入(stdin)中讀入搜尋請求,然後對它進行解析,最後建立一個Lucene中的Query對象。

String querystr = args.length > 0 ? args[0] : "lucene"; Query q = new QueryParser(Version.LUCENE_40, "title", analyzer).parse(querystr);

3.搜尋

我們建立一個Searcher對象并且使用上面建立的Query對象來進行搜尋,比對到的前10個結果封裝在TopScoreDocCollector對象裡傳回。

int hitsPerPage = 10; IndexReader reader = IndexReader.open(index); IndexSearcher searcher = new IndexSearcher(reader); TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); searcher.search(q, collector); ScoreDoc[] hits = collector.topDocs().scoreDocs;

4.展示

現在我們得到了搜尋結果,我們需要想使用者展示它。

System.out.println("Found " + hits.length + " hits."); for(int i=0;i<hits.length;++i) {     int docId = hits[i].doc;     Document d = searcher.doc(docId);     System.out.println((i + 1) + ". " + d.get("isbn") + "\t" + d.get("title"));

這裡是這個小應用的完整代碼。下載下傳HelloLucene.java。

import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.StringField; import org.apache.lucene.document.TextField; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopScoreDocCollector; import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.util.Version; import java.io.IOException; public class HelloLucene {   public static void main(String[] args) throws IOException, ParseException {     // 0. Specify the analyzer for tokenizing text.     //    The same analyzer should be used for indexing and searching     StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_40);     // 1. create the index     Directory index = new RAMDirectory();     IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_40, analyzer);     IndexWriter w = new IndexWriter(index, config);     addDoc(w, "Lucene in Action", "193398817");     addDoc(w, "Lucene for Dummies", "55320055Z");     addDoc(w, "Managing Gigabytes", "55063554A");     addDoc(w, "The Art of Computer Science", "9900333X");     w.close();     // 2. query     String querystr = args.length > 0 ? args[0] : "lucene";     // the "title" arg specifies the default field to use     // when no field is explicitly specified in the query.     Query q = new QueryParser(Version.LUCENE_40, "title", analyzer).parse(querystr);     // 3. search     int hitsPerPage = 10;     IndexReader reader = DirectoryReader.open(index);     IndexSearcher searcher = new IndexSearcher(reader);     TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);     searcher.search(q, collector);     ScoreDoc[] hits = collector.topDocs().scoreDocs;     // 4. display results     System.out.println("Found " + hits.length + " hits.");     for(int i=0;i<hits.length;++i) {       int docId = hits[i].doc;       Document d = searcher.doc(docId);       System.out.println((i + 1) + ". " + d.get("isbn") + "\t" + d.get("title"));     }     // reader can only be closed when there     // is no need to access the documents any more.     reader.close();   }   private static void addDoc(IndexWriter w, String title, String isbn) throws IOException {     Document doc = new Document();     doc.add(new TextField("title", title, Field.Store.YES));     // use a string field for isbn because we don't want it tokenized     doc.add(new StringField("isbn", isbn, Field.Store.YES));     w.addDocument(doc);

可以直接在指令行中使用這個小應用,鍵入java HelloLucene 。

下面可以做什麼?

閱讀下面關于Lucene的書籍。

你需要應該使用Apache Solr代替Apache Lucene嗎?

更多關于Lucene的基本概念

一些與Lucene和搜尋相關的書籍

Lucene 五分鐘教程
Lucene 五分鐘教程
Lucene 五分鐘教程
Lucene 五分鐘教程
Lucene 五分鐘教程
Lucene 五分鐘教程
Lucene 五分鐘教程
Lucene 五分鐘教程
Lucene 五分鐘教程
Lucene 五分鐘教程
Lucene 五分鐘教程
Lucene 五分鐘教程

Github上的基于maven的庫

Mac Luq在Github上的基于maven的庫:

https://github.com/macluq/helloLucene

用下面這條指令下載下傳它:

git clone https://github.com/macluq/helloLucene.git

PS:如果你是Java新手的話,試試下面的指令:

wget http://repo1.maven.org/maven2/org/apache/lucene/lucene-core/4.0.0/lucene-core-4.0.0.jar wget http://repo1.maven.org/maven2/org/apache/lucene/lucene-analyzers-common/4.0.0/lucene-analyzers-common-4.0.0.jar wget http://repo1.maven.org/maven2/org/apache/lucene/lucene-queryparser/4.0.0/lucene-queryparser-4.0.0.jar wget http://www.lucenetutorial.com/code/HelloLucene.java javac -classpath .:lucene-core-4.0.0.jar:lucene-analyzers-common-4.0.0.jar:lucene-queryparser-4.0.0.jar HelloLucene.java java -classpath .:lucene-core-4.0.0.jar:lucene-analyzers-common-4.0.0.jar:lucene-queryparser-4.0.0.jar HelloLucene

你會得到下面的結果:

Found 2 hits. 1. Lucene in Action 2. Lucene for Dummies

Erik,一個可能對你有所幫助的讀者抱怨到:

編譯過程還算順利,但是我不能正常運作這段代碼。在網上搜尋并且自己嘗試了以後發現Lucene的jar檔案必須在classpath中,否則運作不起來。這可能對很多像我這樣的java初學者很多幫助。

安裝Lucene

PS:我發現一些初學者在安裝Lucene時有些困難。

你應該先下載下傳Lucene,然後把它解壓到一個你用于程式設計的目錄。

如果你使用Netbeans,你也可以這麼做:

遵循這裡的教程。

按照下面的步驟:

通過以此點選Netbeans菜單欄上的“工具”,然後選擇“庫管理器”,把Lucene的jar檔案作為外部類庫加進來。

在Lucene項目上面右鍵,選擇“屬性”

在彈出來的對話框中,以此選擇“類庫”,”添加jar或檔案夾”選項

定位到從lucene-[version].tar.gz解壓出來的檔案夾上,選擇 lucene-core-[version].jar。

點選“确定”,現在jar檔案就已經添加到你項目的classpath中去了。