Lucene 3.0 分詞 IKAnalyzer

最近lucene已經更新到lucene 3.0版本了 2.X版本的一些用法已經徹底不在支持了。
下面的例子主要是介紹中文分詞器IKAnalyzer的使用和Lucene高亮顯示。
lucene 3.x版本中有些2.x方法已經完全被剔除了,這裏會捎帶一下3.x的用法,當然我這裏用的還是2.X的版本。
lucene自帶的分詞方式對中文分詞十分的不友好,基本上可以用慘不忍睹來形容,所以這裏推薦使用IKAnalyzer進行中文分詞。
IKAnalyzer分詞器是一個非常優秀的中文分詞器。
下面是官方文檔上的介紹
採用了特有的“正向迭代最細粒度切分算法“,具有60萬字/秒的高速處理能力。
採用了多子處理器分析模式,支持:英文字母(IP地址、Email、URL)、數字(日期,常用中文數量詞,羅馬數字,科學計數法),中文詞彙(姓名、地名處理)等分詞處理。
優化的詞典存儲,更小的內存佔用。支持用戶詞典擴展定義.
針對Lucene全文檢索優化的查詢分析器
IKQueryParser(作者吐血推薦);採用歧義分析算法優化查詢關鍵字的搜索排列組合,能極大的提高Lucene檢索的命中率。
1.IKAnalyzer的部署:將IKAnalyzer3.X.jar部署於項目的lib目錄中;IKAnalyzer.cfg.xml與ext_stopword.dic文件放置在代碼根目錄下即可。
ok 部署完IKAnalyzer我們先來測試一下

package demo.test;

import java.io.IOException;
import java.io.StringReader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.TermAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class TestIKAnalyzer {

public static void main(String[] args) throws IOException {
Analyzer analyzer = new IKAnalyzer();
TokenStream tokenStream = analyzer.tokenStream("", new StringReader("永和服裝飾品有限公司"));
//2.x寫法 3.0之後不支持了

//3.x的寫法
TermAttribute termAtt = (TermAttribute) tokenStream.getAttribute(TermAttribute.class);
TypeAttribute typeAtt = (TypeAttribute) tokenStream.getAttribute(TypeAttribute.class);

while (tokenStream.incrementToken()) {
System.out.print(termAtt.term());
System.out.print(' ');
System.out.println(typeAtt.type());
}
}

}

分詞結果 永和 和服 服裝 裝飾品 裝飾 飾品 有限公司 有限 公司

2.我們開始採用IKAnalyzer創建索引

package demo.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class CreatIndex {

@SuppressWarnings("deprecation")
public static void main(String[] args) throws IOException {
String path = "index";//索引目錄
Analyzer analyzer = new IKAnalyzer();//採用的分詞器
IndexWriter iwriter = new IndexWriter(path, analyzer, true);
File dir = new File("data");//待索引的數據文件目錄
File[] files = dir.listFiles();
for(int i=0;i<files.length;i++){
Document doc = new Document();
File file = files[i];
FileInputStream fis = new FileInputStream(file);
String content = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));

StringBuffer buffer = new StringBuffer("");
content = reader.readLine();
while (content != null) {
buffer.append(content);
content = reader.readLine();
}
doc.add(new Field("title",file.getName(),Field.Store.YES,Field.Index.ANALYZED));
doc.add(new Field("content",buffer.toString(),Field.Store.YES,Field.Index.ANALYZED));
iwriter.addDocument(doc);
}
iwriter.close();
}

}

3.對索引進行查詢並進行高亮highlighter處理

package demo.test;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class TestHighlighter {

@SuppressWarnings("deprecation")
public static void main(String[] args) throws IOException, InvalidTokenOffsetsException {
String path = "index";//索引目錄
Directory dir = FSDirectory.getDirectory(new File(path));
IndexSearcher search = new IndexSearcher(dir);
Term term = new Term("content","純粹");
Query query = new TermQuery(term);
TopDocs topDocs = search.search(query, 10);
ScoreDoc[] hits = topDocs.scoreDocs;
//正常產生的查詢
for(int i=0;i<hits.length;i++){
Document doc = search.doc(hits[i].doc);
System.out.print(doc.get("title")+":");
System.out.println(doc.get("content"));
}
//高亮設置
Analyzer analyzer = new IKAnalyzer();//設定分詞器
SimpleHTMLFormatter simpleHtmlFormatter = new SimpleHTMLFormatter("<B>","</B>");//設定高亮顯示的格式,也就是對高亮顯示的詞組加上前綴後綴
Highlighter highlighter = new Highlighter(simpleHtmlFormatter,new QueryScorer(query));
highlighter.setTextFragmenter(new SimpleFragmenter(150));//設置每次返回的字符數.想必大家在使用搜索引擎的時候也沒有一併把全部數據展示出來吧,當然這裏也是設定只展示部分數據
for(int i=0;i<hits.length;i++){
Document doc = search.doc(hits[i].doc);
TokenStream tokenStream = analyzer.tokenStream("",new StringReader(doc.get("content")));
String str = highlighter.getBestFragment(tokenStream, doc.get("content"));
System.out.println(str);
}
}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章