lucence学习系列之一 基本概念
1. Lucence基本概念
Lucence是一個java編寫的全文檢索類庫,使用它可以為一個應用或者站點增加檢索功能。
它通過增加內容到一個全文索引來完成檢索功能。然后允許你基于這個索引去查詢,返回結果,結果要么根據查詢的相關度來排序要么根據任意字段如文檔最后修改日期來排序。
增加到Lucence的內容可以來自多種數據源,如SQL/NOSQL 數據庫,文件系統,甚至從站點上。
1.1 檢索與索引
Lucence能快速的完成查詢結果,是因為它不是直接搜索的文本,而是搜索一個索引。這類似于通過查詢書后的索引的關鍵字來返回一本書的頁面,而不是在書中的每頁來搜索這個單詞。
這種類型的索引稱之為 反向搜索,因為它反轉了一個頁核心數據結構(頁—>單詞)到關鍵字核心的數據結構(單詞à頁)。
?
1.2 文檔
在lucence中,一個文件是一個搜索和索引的單元,一個索引包含一個或者多個文檔。
構建索引包含增加文檔到一個IndexWriter,搜索包含從通過IndexSearcher來從一個索引中檢索文檔。
?
一個Lucence文檔不必一定是一個常用英語中的單詞文檔。例如,如果你創建一個數據庫的用戶表的lucence索引,那么在索引中每個用戶代表一個lucence文檔。
?
1.3 字段
一個文檔包含一個或者多個字段。一個字段僅僅是一個鍵值對。例如,通常在應用中的title字段。在title字段中,字段名稱為title,值是該title包含的內容。
在lucence中構建索引也包含創建包含一個或者多個字段的文檔,并且增加這些文檔到IndexWriter。
?
1.4 檢索
檢索需要在一個索引已經構建完成后。它包含創建一個查詢(Query)和處理該查詢到IndexSearcher中,然后返回一組Hit。
?
1.5 查詢(Query)
Lucence擁有自己的查詢語言。Lucence查詢語言支持用戶指定查詢的字段,字段的權重,使用聯合查詢如AND/OR/NOT和其它功能。
?
2. lucence如何工作?
lucence工作原理
?
lucence架構如下:
?
2.1. 索引過程:
1) 有一系列被索引文件
2) 被索引文件經過語法分析和語言處理形成一系列詞(Term)。
3) 經過索引創建形成詞典和反向索引表。
4) 通過索引存儲將索引寫入硬盤。
簡單示例:
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()方法是增加文檔到索引中。
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); }?
2.2 搜索過程:
a) 用戶輸入查詢語句。
b) 對查詢語句經過語法分析和語言分析得到一系列詞(Term)。
c) 通過語法分析得到一個查詢樹。
d) 通過索引存儲將索引讀入到內存。
e) 利用查詢樹搜索索引,從而得到每個詞(Term)的文檔鏈表,對文檔鏈表進行交,差,并得到結果文檔。
f) 將搜索到的結果文檔對查詢的相關性進行排序。
g) 返回查詢結果給用戶。
搜索一般三步,如下:
2.2.1 構建查詢語句
示例:
String querystr = args.length > 0 ? args[0] : "lucene"; Query q = new QueryParser(Version.LUCENE_40, "title", analyzer).parse(querystr);2.2.2 搜索前10
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;2.2.3 展示結果
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")); }2.3 完整過程
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 searchingStandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_40);// 1. create the indexDirectory 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. queryString 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. searchint 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 resultsSystem.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 tokenizeddoc.add(new StringField("isbn", isbn, Field.Store.YES));w.addDocument(doc);} }?參考文獻:
【1】http://www.lucenetutorial.com/
【2】?http://www.cnblogs.com/forfuture1978/archive/2010/06/13/1757479.html
轉載于:https://www.cnblogs.com/davidwang456/p/4730000.html
總結
以上是生活随笔為你收集整理的lucence学习系列之一 基本概念的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Exchanging Partition
- 下一篇: solr4.2增量索引之同步(修改,删除