lucene 建立索引與查詢

來源:互聯網
上載者:User

標籤:搜尋引擎   應用程式   工具包   java   流行   

Lucene 簡介

Lucene 是一個基於 Java 的全文資訊檢索工具包,它不是一個完整的搜尋應用程式,而是為你的應用程式提供索引和搜尋功能。Lucene 目前是 Apache Jakarta 家族中的一個開源項目。也是目前最為流行的基於 Java 開源全文檢索索引工具包。

目前已經有很多應用程式的搜尋功能是基於 Lucene 的,比如 Eclipse 的協助系統的搜尋功能。Lucene 能夠為文本類型的資料建立索引,所以你只要能把你要索引的資料格式轉化的文本的,Lucene 就能對你的文檔進行索引和搜尋。比如你要對一些 HTML 文檔,PDF 文檔進行索引的話你就首先需要把 HTML 文檔和 PDF 文檔轉化成文字格式設定的,然後將轉化後的內容交給 Lucene 進行索引,然後把建立好的索引檔案儲存到磁碟或者記憶體中,最後根據使用者輸入的查詢條件在索引檔案上進行查詢。不指定要索引的文檔的格式也使 Lucene 能夠幾乎適用於所有的搜尋應用程式。

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/4C/9D/wKiom1RBIT3TkNBRAAGiDYQk5-I749.jpg" title="UF6I@~NSXADIAVR~WII8U}L.jpg" alt="wKiom1RBIT3TkNBRAAGiDYQk5-I749.jpg" />

索引和搜尋

索引是現代搜尋引擎的核心,建立索引的過程就是把來源資料處理成非常方便查詢的索引檔案的過程。為什麼索引這麼重要呢,試想你現在要在大量的文檔中搜尋含有某個關鍵詞的文檔,那麼如果不建立索引的話你就需要把這些文檔順序的讀入記憶體,然後檢查這個文章中是不是含有要尋找的關鍵詞,這樣的話就會耗費非常多的時間,想想搜尋引擎可是在毫秒級的時間內尋找出要搜尋的結果的。這就是由於建立了索引的原因,你可以把索引想象成這樣一種資料結構,他能夠使你快速的隨機訪問儲存在索引中的關鍵詞,進而找到該關鍵詞所關聯的文檔。Lucene 採用的是一種稱為反向索引(inverted index)的機制。反向索引就是說我們維護了一個詞 / 短語表,對於這個表中的每個詞 / 短語,都有一個鏈表描述了有哪些文檔包含了這個詞 / 短語。這樣在使用者輸入查詢條件的時候,就能非常快的得到搜尋結果。我們將在本系列文章的第二部分詳細介紹 Lucene 的索引機制,由於 Lucene 提供了簡單易用的 API,所以即使讀者剛開始對全文本進行索引的機制並不太瞭解,也可以非常容易的使用 Lucene 對你的文檔實現索引。

對文檔建立好索引後,就可以在這些索引上面進行搜尋了。搜尋引擎首先會對搜尋的關鍵詞進行解析,然後再在建立好的索引上面進行尋找,最終返回和使用者輸入的關鍵詞相關聯的文檔。

Lucene 軟體包分析

Lucene 軟體包的發布形式是一個 JAR 檔案,下面我們分析一下這個 JAR 檔案裡面的主要的 JAVA 包,使讀者對之有個初步的瞭解。

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 用來儲存搜尋得到的結果。

一個簡單的搜尋應用程式

假設我們的電腦的目錄中含有很多文字文件,我們需要尋找哪些文檔含有某個關鍵詞。為了實現這種功能,我們首先利用 Lucene 對這個目錄中的文檔建立索引,然後在建立好的索引中搜尋我們所要尋找的文檔。通過這個例子讀者會對如何利用 Lucene 構建自己的搜尋應用程式有個比較清楚的認識。

建立索引

為了對文檔進行索引,Lucene 提供了五個基礎的類,他們分別是 Document, Field, IndexWriter, Analyzer, Directory。下面我們分別介紹一下這五個類的用途:

Document

Document 是用來描述文檔的,這裡的文檔可以指一個 HTML 頁面,一封電子郵件,或者是一個文字檔。一個 Document 對象由多個 Field 對象組成的。可以把一個 Document 對象想象成資料庫中的一個記錄,而每個 Field 對象就是記錄的一個欄位。

Field

Field 對象是用來描述一個文檔的某個屬性的,比如一封電子郵件的標題和內容可以用兩個 Field 對象分別描述。

Analyzer

在一個文檔被索引之前,首先需要對文檔內容進行分詞處理,這部分工作就是由 Analyzer 來做的。Analyzer 類是一個抽象類別,它有多個實現。針對不同的語言和應用需要選擇適合的 Analyzer。Analyzer 把分詞後的內容交給 IndexWriter 來建立索引。

IndexWriter

IndexWriter 是 Lucene 用來建立索引的一個核心的類,他的作用是把一個個的 Document 對象加到索引中來。

Directory

這個類代表了 Lucene 的索引的儲存的位置,這是一個抽象類別,它目前有兩個實現,第一個是 FSDirectory,它表示一個儲存在檔案系統中的索引的位置。第二個是 RAMDirectory,它表示一個儲存在記憶體當中的索引的位置。


下面是程式碼

先是建立索引的代碼

import java.io.File;

import java.io.FileReader;

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;

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;

/** 

* This class demonstrate the process of creating index with Lucene 

* for text files 

*/ 

public class TxtFileIndexer { 

     public static void addindex(String path) throws Exception{ 

     

    Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);  

         Directory directory = FSDirectory.open(new File("D:\\lucenetext\\luceneIndex")); 

         File   dataDir  = new File(path);

         File[] dataFiles  = dataDir.listFiles();

         IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer);  

         IndexWriter iwriter = new IndexWriter(directory, config);  

         

         for(int i = 0; i < dataFiles.length; i++){ 

             if(dataFiles[i].isFile() && dataFiles[i].getName().endsWith(".txt")){

                  System.out.println("Indexing file " + dataFiles[i].getCanonicalPath()); 

                  Document document = new Document(); 

                  Reader txtReader = new FileReader(dataFiles[i]); 

                  document.add(new Field("path", dataFiles[i].getCanonicalPath(), TextField.TYPE_STORED));

                  document.add(new Field("content", txtReader, TextField.TYPE_NOT_STORED));

                  iwriter.addDocument(document); 

             } 

        }

          

         iwriter.close();  

         System.out.println("建立索引 ok");

     }

}

搜尋文檔

利用 Lucene 進行搜尋就像建立索引一樣也是非常方便的。在上面一部分中,我們已經為一個目錄下的文字文件建立好了索引,現在我們就要在這個索引上進行搜尋以找到包含某個關鍵詞或短語的文檔。Lucene 提供了幾個基礎的類來完成這個過程,它們分別是呢 IndexSearcher, Term, Query, TermQuery, Hits. 下面我們分別介紹這幾個類的功能。

Query

這是一個抽象類別,他有多個實現,比如 TermQuery, BooleanQuery, PrefixQuery. 這個類的目的是把使用者輸入的查詢字串封裝成 Lucene 能夠識別的 Query。

Term

Term 是搜尋的基本單位,一個 Term 對象有兩個 String 類型的域組成。產生一個 Term 對象可以有如下一條語句來完成:Term term = new Term(“fieldName”,”queryWord”); 其中第一個參數代表了要在文檔的哪一個 Field 上進行尋找,第二個參數代表了要查詢的關鍵詞。

TermQuery

TermQuery 是抽象類別 Query 的一個子類,它同時也是 Lucene 支援的最為基本的一個查詢類。產生一個 TermQuery 對象由如下陳述式完成: TermQuery termQuery = new TermQuery(new Term(“fieldName”,”queryWord”)); 它的建構函式只接受一個參數,那就是一個 Term 對象。

IndexSearcher

IndexSearcher 是用來在建立好的索引上進行搜尋的。它只能以唯讀方式開啟一個索引,所以可以有多個 IndexSearcher 的執行個體在一個索引上進行操作。

然後是查詢代碼:

import java.io.File;


import org.apache.lucene.analysis.Analyzer;

import org.apache.lucene.analysis.standard.StandardAnalyzer;

import org.apache.lucene.document.Document;

import org.apache.lucene.index.DirectoryReader;

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.store.Directory;

import org.apache.lucene.store.FSDirectory;

import org.apache.lucene.util.Version;



 /** 

 * This class is used to demonstrate the 

 * process of searching on an existing 

 * Lucene index 

 * 

 */ 

 public class TxtFileSearcher { 

public static void search(String queryStr) throws Exception{ 

  

        File indexDir = new File("D:\\lucenetext\\luceneIndex"); 

        Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);

        // Now search the index:  

        Directory directory = FSDirectory.open(indexDir); 

        DirectoryReader ireader = DirectoryReader.open(directory);  

        IndexSearcher isearcher = new IndexSearcher(ireader);

        

        // Parse a simple query that searches for "text":  

        QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "content", analyzer);  

        Query query = parser.parse(queryStr);  

        ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs;  

        

        System.out.println("there are " + hits.length + "result");

        // Iterate through the results:  

        for (int i = 0; i < hits.length; i++) {  

          Document hitDoc = isearcher.doc(hits[i].doc);  

          System.out.println(hitDoc.get("path")+"*****************"+hitDoc.get("content"));  

        }  

        ireader.close();  

        directory.close(); 

 }


OK,這樣一個基於Lucene的查詢就完成了。

lucene 建立索引與查詢

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.