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; }