lucene全文搜索之二:創建索引器(創建IKAnalyzer分詞器和索引目錄管理)基於lucene5.5.3

  • 2019 年 11 月 1 日
  • 筆記

版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/eguid_1/article/details/53086836

前言:

lucene全文搜索之一中講解了lucene開發搜索服務的基本結構,本章將會講解如何創建索引器、管理索引目錄和中文分詞器的使用。

包括標準分詞器,IKAnalyzer分詞器以及兩種索引目錄的創建

luncene5.5.3集合jar包下載地址:http://download.csdn.net/detail/eguid_1/9677589

一、創建索引器

創建lucene的索引器需要兩個要素:一個是分詞器,一個是索引目錄。

那麼就讓我們創建這兩個實例

1、創建分詞器

(1)創建lucene內置分詞器

/**  	 * 創建內置分詞器  	 * @param stopwords CharArraySet停詞  	 * @param stopWords Reader停詞  	 * @param 都為null則返回默認分詞器  	 * @return 分詞器  	 * @throws IOException  	 */  	public Analyzer createAnalyzer(CharArraySet stopwords, Reader stopWords) throws IOException {  		StandardAnalyzer analyzer = null;  		if (stopwords != null) {  			analyzer = new StandardAnalyzer(stopwords);  		} else if (stopWords != null) {  			try {  				analyzer = new StandardAnalyzer(stopWords);  			} catch (IOException e) {  				throw e;  			}  		} else {  			analyzer = new StandardAnalyzer();  		}  		return analyzer;  	}

(2)創建IKAnalyzer分詞器

IKAnalyzer源碼及配置使用請查看使用IK Analyzer中文分詞器(修改IK Analyzer源碼使其支援lucene5.5.x)

/**  	 * 創建IKAnalyzer分詞器  	 * @param isSmart -true:智慧分詞,false:最細粒度分詞  	 * @return  	 */  	public Analyzer createAnalyzer(boolean isSmart)  	{  		return new IKAnalyzer(isSmart);  	}

2、創建索引目錄

索引目錄分為文件目錄和記憶體虛擬目錄

(1)創建索引文件目錄

/**  	 * 創建文件目錄  	 * @param path -路徑  	 * @param lockFactory -文件鎖  	 * @return Directory -索引目錄  	 * @throws IOException -路徑錯誤導致IO異常  	 */  	public Directory createDirectory(Path path, LockFactory lockFactory) throws IOException {  		FSDirectory dir = null;  		// 打開目錄  		try {  			if (lockFactory == null)  				dir = FSDirectory.open(path);  			else  				dir = FSDirectory.open(path, lockFactory);  		} catch (IOException e) {  			throw e;  		}  		return dir;  	}  	/**  	 * 創建文件目錄  	 * 路徑格式:「d:」,「dir」,「search」 等於 「d://dir/search」  	 * @param lockFactory -文件鎖  	 * @param first -路徑  	 * @param more -路徑  	 * @return Directory -索引目錄  	 * @throws IOException  	 */  	public Directory createDirectory(LockFactory lockFactory,String first,String ...more) throws IOException{  		Path path=FileSystems.getDefault().getPath(first,more);  		return createDirectory(path,lockFactory);  	}

(2)創建記憶體虛擬索引目錄

public RAMDirectory createRAMDirectory(LockFactory lockFactory, FSDirectory dir, IOContext context)  			throws IOException {  		RAMDirectory ramDirectory = null;  		if (lockFactory != null) {  			ramDirectory = new RAMDirectory(lockFactory);  		} else if (dir != null && context != null) {  			try {  				ramDirectory = new RAMDirectory(dir, context);  			} catch (IOException e) {  				throw e;  			}  		} else {  			ramDirectory = new RAMDirectory();  		}  		return ramDirectory;  	}

創建完了分詞器和索引目錄,那麼我們就可以通過這兩個要素構建索引配置

3、創建索引配置

/**  	 * 根據分詞器創建索引配置  	 * @param analyzer -分詞器可以選擇默認也可以使用IK或者庖丁  	 * @param openMode -模式(有三種模式:OpenMode.APPEND -增加;OpenMode.CREATE -創建;OpenMode.CREATE_OR_APPEND -創建和增加;)  	 * @param commitOnClose -是否關閉時才提交索引  	 * @return  	 */  	public IndexWriterConfig createIndexConf(Analyzer analyzer,OpenMode openMode,boolean commitOnClose) {  		IndexWriterConfig indexConf = null;  		if (analyzer != null) {  			indexConf = new IndexWriterConfig(analyzer);  			indexConf.setOpenMode(openMode);//一般使用OpenMode.CREATE_OR_APPEND  			indexConf.setCommitOnClose(commitOnClose);//默認是true:索引器關閉後才提交索引,false就是手動提交索引  		}  		return indexConf;  	}

創建完索引配置,就可以根據配置創建一個索引器了

4、根據配置和索引目錄創建索引

/**  	 * 創建索引器  	 * @param dir -索引目錄  	 * @param indexConf -索引配置  	 * @return IndexWriter 返回索引器  	 * @throws IOException  	 */  	public IndexWriter createIndex(Directory dir,IndexWriterConfig indexConf) throws IOException {  		IndexWriter indexWriter =null;  		try {  			indexWriter=new IndexWriter(dir, indexConf);  		} catch (IOException e) {  			throw e;  		}  		return indexWriter;  	}

有了索引器,我們就可以對索引進行增刪查了(沒有改)

5、索引器的增刪改

重要:lucene中索引只有增刪查的API,沒有更新/改的API,如果想要更新/改 索引必須先刪掉索引再添加

/**  	 * 增加索引  	 * @param indexWriter  	 * @param doc  	 * @return  	 */  	public boolean addIndex(IndexWriter indexWriter, Document doc) {  		boolean ret = true;  		if (indexWriter != null && indexWriter.isOpen() && doc != null) {  			try {  				indexWriter.addDocument(doc);  				indexWriter.commit();//commitOnClose設置為false,這裡就需要手動提交,否則關閉索引器後不會自動提交  			} catch (IOException e) {  				ret = false;  			}  		}  		return ret;  	}  	/**  	 * 根據詞語刪除索引  	 * @param indexWriter  	 * @param terms  	 * @return  	 */  	public boolean removeIndex(IndexWriter indexWriter, Term ...terms){  		boolean ret = true;  		if (indexWriter != null && indexWriter.isOpen() && terms != null) {  			try {  				indexWriter.deleteDocuments(terms);    			} catch (IOException e) {  				ret = false;  			}  		}  		return ret;  	}  	/**  	 * 刪除搜索結果對應的索引  	 * @param indexWriter  	 * @param querys  	 * @return  	 */  	public boolean removeIndex(IndexWriter indexWriter, Query ...querys){  		boolean ret = true;  		if (indexWriter != null && indexWriter.isOpen() && querys != null) {  			try {  				indexWriter.deleteDocuments(querys);  			} catch (IOException e) {  				ret = false;  			}  		}  		return ret;  	}

不需要使用索引,也可以這樣關閉索引

6、關閉索引器

/**  	 * 關閉索引器  	 * @param indexWriter  	 * @param commitOnClose -關閉時是否提交索引(防止正在創建的索引沒有及時提交)  	 * @return true:關閉成功:關閉失敗  	 */  	public boolean close(IndexWriter indexWriter, boolean commitOnClose) {  		boolean ret = false;  		if (indexWriter != null && indexWriter.isOpen()) {  			try {  				if (commitOnClose) {  					indexWriter.flush();  					indexWriter.commit();  				}  				indexWriter.close();  				ret=true;  			} catch (IOException e) {  				try {  					//防止提交時異常導致索引關閉失敗,再次嘗試關閉  					indexWriter.close();  					ret=true;  				} catch (IOException e1) {  					ret=false;  				}  			}  		}  		return ret;  	}