Lucene入門——基礎知識

Lucene簡介

    Lucene是一個基於Java的全文信息檢索工具包,爲應用程序提供索引和搜索功能。
    Lucene採用的是一種稱爲反向索引(inverted index)的機制。反向索引就是說咱們維護一個詞/短語表,對於這個詞/短語表再經過一個鏈表標示哪些文檔包含了這個詞、短語。這樣在用戶輸入查詢條件的時候,就能很是快的查找到搜索結果。對文檔建好索引後,能夠基於索引進行搜索。搜索引擎首先會對搜索的關鍵詞進行解析,而後再在創建好的索引上查找,最終返回和用戶輸入的關鍵詞相關聯的文檔。

Lucene軟件包分析

    五種基本包:
    Package: org.apache.lucene.document
    這個包提供了一些爲封裝要索引的文檔所須要的類,好比Document,Field。這樣,每個文檔最終被封裝成了一個Document對象。
    Package: org.apache.lucene.analysis
    這個包主要功能是對文檔進行分詞,由於文檔在創建索引以前必需要進行分詞,因此這個包的做用能夠當作是爲創建索引作準備工做。
    Package: org.apache.lucene.index
    這個包提供了一些類來協助建立索引以及對建立好的索引進行更新。這裏面有兩個基礎的類:IndexWriter和IndexReader,其中IndexWriter是用來建立索引並添加文檔到索引中的,IndexReader是用來刪除索引中的文檔的。
    Package: org.apache.lucene.search
    這個包提供了對在創建好的索引上進行搜索所須要的類。好比IndexSearcher和Hits,IndexSearcher定義了在指定的索引上進行搜索的方法,Hits用來保存搜索獲得的結果。

 

    五種基本類簡介:
  1. Document: Documentg是用來描述文檔的,這裏的文檔能夠指一個HTML頁面,一封電子郵件,或一個文本文件。一個Document存在多個fields,每個field有一個名字和文本類容。
  2. Field:Field對象用來面試文檔的屬性,含有一個名字和內容。好比電子郵件的標題,就存在標題和對應的標題內容。
  3. Analyzer:   分詞處理。一個文檔在被索引前,都須要進行分詞處理。分詞處理比較複雜的要屬中文的分詞處理,不過如今都有比較成熟的框架來完成。
  4. IndexWriter:IndexWriter是Lucene用來建立索引的核心類,用於將Document對象加入到內存中。
  5. Directory:表明Lucene的索引存儲的位置,這是一個抽象類。 FSDirectory,表示存儲在文件系統的索引位置。RAMDirectory表示一個存儲在內存中的索引的位置。

創建文本索引例子

    本例子基於Lucene代碼版本爲:4.10.4。因此部分代碼可能與原文不一致。
package test;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
/**
 * 文本文件創建索引
 * 
 * @author jing
 *
 */
public class TxtFileIndexer {
    private static final String DATA_DIR = "E:\\luceneData";// 數據存儲位置
    private static final String INDEX_DIR = "E:\\luceneIndex";// 索引文件位置
    private static Directory diskDir;// 索引存儲位置
    // 加載索引Directory
    static {
        try {
            diskDir = FSDirectory.open(new File(INDEX_DIR));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws IOException {
        // 數據存儲位置
        File dataDir = new File(DATA_DIR);
        // 分詞器
        Analyzer luceneAnalyzer = new StandardAnalyzer();
        File[] dataFiles = dataDir.listFiles();
        // 索引
        IndexWriter indexWriter = new IndexWriter(diskDir, new IndexWriterConfig(Version.LATEST,
                luceneAnalyzer));
        long startTime = System.currentTimeMillis();
        for (File dataFile : dataFiles) {
            if (dataFile.isFile() && dataFile.getName().endsWith(".txt")) {
                System.out.println("分詞器分詞,文件: " + dataFile.getName());
                Document document = new Document();
                Reader txtReader = new FileReader(dataFile);
                document.add(new TextField("path", dataFile.getCanonicalPath(), Store.YES));
                //讀取文件內容
                char[] ch = new char[10240];
                while( txtReader.read(ch) != -1){
                    
                    continue;
                }
                document.add(new TextField("contents", String.valueOf(ch), Store.YES));
                indexWriter.addDocument(document);
                txtReader.close();
            }
        }
        indexWriter.close();
        long endTime = System.currentTimeMillis();
        System.out.println("It takes " + (endTime - startTime)
                + " milliseconds to create index for the files in directory " + dataDir.getPath());
    }
}

 

 

輸出結果:
    分詞器分詞,文件:1-副本(2).txt
    分詞器分詞,文件:1-副本(3).txt
    分詞器分詞,文件:1-副本(4).txt
    分詞器分詞,文件:1-副本(5).txt
    分詞器分詞,文件:1-副本(6).txt
    分詞器分詞,文件:1-副本.txt
    分詞器分詞,文件:1.txt
    It takes 375 milliseconds to create index for the files in directory E:\luceneData

 

搜索文檔類分析

  1. Query:抽象類,將用戶輸入的字符串分裝爲特定的對象。
  2. Term:搜索的基本單位,一個Term對象有兩個String類型的域組成。一個參數表明文檔File,一個參數表示查詢的關鍵字。
  3. TermQuery:Query的子類,同時是Lucene支持的最基本的查詢類。
  4. IndexSearch:在創建好的索引上進行搜索。只能以只讀的方式打開索引。
  5. Hits:保存搜索結果。本人使用的API已經更改,使用ScoreDoc來保存。

搜索實例

    
package test;
import java.io.File;
import java.io.IOException;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
public class TxtFileSearch {
    
    private static final String INDEX_DIR = "E:\\luceneIndex";// 索引文件位置
    
    private static Directory diskDir;// 索引存儲位置
    
 // 加載索引Directory
    static {
        try {
            diskDir = FSDirectory.open(new File(INDEX_DIR));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws IOException {
        
        IndexSearcher searcher  = new IndexSearcher(DirectoryReader.open(diskDir));
        Term term = new Term("contents", "searcher");
        TermQuery luceneQuery = new TermQuery(term); 
        
        //Finds the top n hits for query
        ScoreDoc[] hitsAfter = searcher.search(luceneQuery, 500).scoreDocs;
        for(ScoreDoc sDoc : hitsAfter){ 
                
            Document hitDoc = searcher.doc(sDoc.doc);
            System.out.println(hitDoc.get("path"));
        } 
    }
}

 

 

總結

    本文根據 http://www.ibm.com/developerworks/cn/java/j-lo-lucene1/#icomments    文章整理而來。
    其中,由於api版本問題,本文對部分代碼進行了修改。
    本文演示了一個基本的Lucene操做,能夠認爲是一個基本的入門程序。
相關文章
相關標籤/搜索