1. 程式人生 > >基於lucene的案例開發:建立索引

基於lucene的案例開發:建立索引

      從這篇部落格開始,不論是API介紹還是後面的案例開發,都是基於 lucene4.3.1 這個版本,Lucene4.3.1 下載請點選這裡, Lucene其他版本下載請點選這裡,Lucene4.3.1官方API文件請點選這裡

建立索引demo

      在開始介紹之前,先看一個簡單的索引建立demo程式:

 /**  
 *@Description:   索引建立demo
 */ 
package com.lulei.lucene.study;  

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.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.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
  
public class IndexCreate {

	public static void main(String[] args) {
		//指定索引分詞技術,這裡使用的是標準分詞
		Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_43);
		//indexwriter 配置資訊
		IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_43, analyzer);
		//索引的開啟方式,沒有索引檔案就新建,有就開啟
		indexWriterConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
		Directory directory = null;
		IndexWriter indexWrite = null;
		try {
			//指定索引硬碟儲存路徑
			directory = FSDirectory.open(new File("D://study/index/testindex"));
			//如果索引處於鎖定狀態,則解鎖
			if (IndexWriter.isLocked(directory)){
				IndexWriter.unlock(directory);
			}
			//指定所以操作物件indexWrite
			indexWrite = new IndexWriter(directory, indexWriterConfig);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		//建立文件一
		Document doc1 = new Document();
		//對name域賦值“測試標題”,儲存域值資訊
		doc1.add(new TextField("name", "測試標題", Store.YES));
		//對content域賦值“測試標題”,儲存域值資訊
		doc1.add(new TextField("content", "測試內容", Store.YES));
		try {
			//將文件寫入到索引中
			indexWrite.addDocument(doc1);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		//建立文件二
		Document doc2 = new Document();
		doc2.add(new TextField("name", "基於lucene的案例開發:索引數學模型", Store.YES));
		doc2.add(new TextField("content", "lucene將一篇文件分成若干個域,每個域又分成若干個詞元,通過詞元在文件中的重要程度,將文件轉化為N維的空間向量,通過計算兩個向量之間的夾角餘弦值來計算兩個文件的相似程度", Store.YES));
		try {
			//將文件寫入到索引中
			indexWrite.addDocument(doc2);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		//將indexWrite操作提交,如果不提交,之前的操作將不會儲存到硬碟
		try {
			//這一步很消耗系統資源,所以commit操作需要有一定的策略
			indexWrite.commit();
			//關閉資源
			indexWrite.close();
			directory.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
      在上述的程式中,已做了詳細的註釋,對每一條語句的作用就不再介紹,下面就看一下執行這個main函式之後建立的索引檔案,如下圖:


      通過索引檢視工具 luke 可以簡單的看下索引中的內容,如下圖:



      從上面兩張圖,我們可以看出索引中一共有兩個文件,content域有50個詞,name域有18個詞,索引中儲存了文件的詳細資訊。

建立索引核心類

      在上述建立索引過程中,用到了幾個核心類:IndexWriterDirectoryAnalyzerDocumentField

IndexWriter

      IndexWriter(寫索引)是索引過程中的核心元件,這個類負責建立新的索引或開啟已有的索引以及向索引中新增、刪除、更新被索引的文件資訊;IndexWriter需要開闢一定空間來儲存索引,該功能可以由Directory完成。

Directory

      Directory類描述了Lucene索引的存放位置。它是一個抽象類,它的子類負責指定索引的儲存路徑,在前面的例子中,我們用的是FSDirectory.open方法來獲取真實檔案在檔案系統中的儲存路徑,然後將他們依次傳遞給IndexWriter類構造方法。

Analyzer

      文件資訊在被索引之前需要經過Analyzer(分析器)處理,上述例子中使用的是標準分詞,在以後的部落格中會單獨介紹各種分詞器以及使用場景。

Document

      Document物件的結構比較簡單,為一個包含多個Field物件的容器,上述事例中的文件就包含兩個域 name、 content。

Filed

      索引中的每一個文件都包含一個或多個域不同命名的域,每個域都有一個域名和對應的域值以及一組選項來精確控制Lucene索引操作各個域值。在搜尋時,所有域的文字就好像連線在一起,作為一個文字域來處理。

上述幾個核心類在Lucene的操作中非常重要而且常用,如需要詳細瞭解,還請參照官方API文件