原文來(lái)自:http://www.lietu.com/doc/Highlighter.htm
1、問(wèn)題的來(lái)源
增加分詞以后結果的準確度提高了,但是用戶(hù)反映返回結果的速度很慢。原因是,Lucene做每一篇文檔的相關(guān)關(guān)鍵詞的高亮顯示時(shí),在運行時(shí)執行了很多遍的分詞操作。這樣降低了性能。
2、解決方法
在Lucene1.4.3版本中的一個(gè)新功能可以解決這個(gè)問(wèn)題。Term Vector現在支持保存Token.getPositionIncrement() 和Token.startOffset() 以及Token.endOffset() 信息。利用Lucene中新增加的Token信息的保存結果以后,就不需要為了高亮顯示而在運行時(shí)解析每篇文檔。通過(guò)Field方法控制是否保存該信息。修改HighlighterTest.java的代碼如下:
//增加文檔時(shí)保存Term位置信息。
private void addDoc(IndexWriter writer, String text) throws IOException
{
Document d = new Document();
//Field f = new Field(FIELD_NAME, text, true, true, true);
Field f = new Field(FIELD_NAME, text ,
Field.Store.YES, Field.Index.TOKENIZED,
Field.TermVector.WITH_POSITIONS_OFFSETS);
d.add(f);
writer.addDocument(d);
}
//利用Term位置信息節省Highlight時(shí)間。
void doStandardHighlights() throws Exception
{
Highlighter highlighter =new Highlighter(this,new QueryScorer(query));
highlighter.setTextFragmenter(new SimpleFragmenter(20));
for (int i = 0; i < hits.length(); i++)
{
String text = hits.doc(i).get(FIELD_NAME);
int maxNumFragmentsRequired = 2;
String fragmentSeparator = "...";
TermPositionVector tpv = (TermPositionVector)reader.getTermFreqVector(hits.id(i),FIELD_NAME);
//如果沒(méi)有stop words去除還可以改成 TokenSources.getTokenStream(tpv,true); 進(jìn)一步提速。
TokenStream tokenStream=TokenSources.getTokenStream(tpv);
//analyzer.tokenStream(FIELD_NAME,new StringReader(text));
String result =
highlighter.getBestFragments(
tokenStream,
text,
maxNumFragmentsRequired,
fragmentSeparator);
System.out.println("\t" + result);
}
}
最后把highlight包中的一個(gè)額外的判斷去掉。對于中文來(lái)說(shuō)沒(méi)有明顯的單詞界限,所以下面這個(gè)判斷是錯誤的:
tokenGroup.isDistinct(token)
這樣中文分詞就不會(huì )影響到查詢(xún)速度了。
聯(lián)系客服