前面幾章把lucene基本入門的任督二脈給打通了,今後篇開始,就開始進行lucene的進階開發了,那麼首先擺在咱們前面的第一個必需要解決的問題,就是關於中文分詞的問題,由於lucene畢竟是國外大牛們開發的,顯然會比較側重英文文章,不過還好,在lucene的下載包裏同步了SmartCN的分詞器針對中文發行的,每一次lucene有新的發行版本,這個包同時更新。
java
筆者比較推薦的中文分詞器是IK分詞器,在進入正式的講解以前,咱們首先對lucene裏面內置的幾個分析器作個瞭解。
apache
評價一個分詞器的性能優劣,關鍵是看它的切詞效率以及靈活性,及擴展性,一般狀況下,一個良好的中文分詞器,應該具有擴展詞庫,禁用詞庫和同義詞庫,固然最關鍵的仍是得要與本身的業務符合,由於有些時候咱們用不到一些自定義詞庫,因此選擇分詞器就能夠不考慮這一點。IK官網發佈的最新版IK分詞器對於lucene的支持是不錯的,可是對已solr的支持就不夠好了,須要本身修改源碼支持solr4.x的版本。筆者使用的另外一個IK包是通過一些人修改過的能夠支持solr4.3的版本。並對擴展詞庫,禁用詞庫,同義詞庫徹底支持,並且在solr裏面配置很簡單,只須要在schmal.xml進行簡單配置,既可以使用IK分詞器的強大定製化功能。不過官網上IK做者發佈的IK包在lucene裏面的確都不支持同義詞庫擴展的功能,若是你想使用,得須要本身修改下源碼了,不過即便本身修改擴展同義詞也是很是容易的。
編輯器
下面筆者給出使用官網最後一版發佈的IK在lucene中作的測試,筆者使用的已經擴展了同義詞庫部分,後面會給出源碼。
ide
下面先看第一個純分詞的測試:性能
package com.ikforlucene; import java.io.StringReader; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; public class Test { public static void main(String[] args)throws Exception { //下面這個分詞器,是通過修改支持同義詞的分詞器 IKSynonymsAnalyzer analyzer=new IKSynonymsAnalyzer(); String text="三劫散仙是一個菜鳥"; TokenStream ts=analyzer.tokenStream("field", new StringReader(text)); CharTermAttribute term=ts.addAttribute(CharTermAttribute.class); ts.reset();//重置作準備 while(ts.incrementToken()){ System.out.println(term.toString()); } ts.end();// ts.close();//關閉流 } }
運行結果:
測試
第二步,測試擴展詞庫,使三劫爲一個詞,散仙爲一個次,須要在同義詞庫裏添加三劫、散仙(注意是按行讀取的),注意保存的格式爲utf-8或無bom格式便可。(轉者注:一、這裏是指文字編輯器中文件保存的格式 二、注意所編輯的文件名稱:這裏是ext.dic)spa
添加擴展詞庫後運行結果以下:
code
第三步,測試禁用詞庫,咱們把菜鳥2個字給屏蔽掉,每行一個詞,保存格式同上。(轉者注:注意所編輯的文件名稱:這裏是stopword.dic)orm
添加禁用詞後運行的結果以下:xml
最後咱們再來測試下,同義詞部分,如今筆者把河南人、洛陽人做爲"一個"這個詞的同義詞,添加到同義詞庫中(筆者在這裏僅僅是作一個測試,真正生產環境中的同義詞確定是正式的),之一同義詞,也是按行讀取的,每行的同義詞之間使用逗號分隔。
添加同義詞庫後運行結果以下:
至此,使用IK在lucene4.3中大部分功能都已測試經過,下面給出擴展同義詞部分的源碼,有興趣的道友們,能夠參考借鑑下。(轉者注:下面所給出的源碼是沒有怎麼對同義詞進行位置插入等等的轉換的)
package com.ikforlucene; import java.io.IOException; import java.io.Reader; import java.util.HashMap; import java.util.Map; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.Tokenizer; import org.apache.lucene.analysis.synonym.SynonymFilterFactory; import org.apache.solr.core.SolrResourceLoader; import org.wltea.analyzer.lucene.IKTokenizer; /** * 能夠加載同義詞庫的Lucene * 專用IK分詞器 * * * */ public class IKSynonymsAnalyzer extends Analyzer { @Override protected TokenStreamComponents createComponents(String arg0, Reader arg1) { Tokenizer token=new IKTokenizer(arg1, true);//開啓智能切詞 Map<String, String> paramsMap=new HashMap<String, String>(); paramsMap.put("luceneMatchVersion", "LUCENE_43"); paramsMap.put("synonyms", "E:\\同義詞\\synonyms.txt"); SynonymFilterFactory factory=new SynonymFilterFactory(paramsMap); SolrResourceLoader loader= new SolrResourceLoader(""); try { factory.inform(loader); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return new TokenStreamComponents(token, factory.create(token)); } }
關於同義詞部分的使用,各位道友,能夠先去官網上下載源碼,而後將此同義詞擴展部分方進入便可,很是簡單方便。