鹰翔宇空

学习和生活

BlogJava 首页 新随笔 联系 聚合 管理
  110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks
引自:http://www.gamvan.com/developer/java/opener/2005/12/849.html

1、问题的来源 增加分词以后结果的准确度提高了,但是用户反映返回结果的速度很慢。原因是, Lucene 做每一篇文档的相关关键词的高亮显示时,在运行时执行了很多遍的分词操作。这样降低了性能。
2 、解决方法 
在 Lucene1.4.3 版本中的一个新功能可以解决这个问题。 Term Vector 现在支持保存 Token.getPositionIncrement() 和 Token.startOffset() 以及 Token.endOffset() 信息。利用 Lucene 中新增加的 Token 信息的保存结果以后,就不需要为了高亮显示而在运行时解析每篇文档。通过 Field 方法控制是否保存该信息。修改 HighlighterTest.java 的代码如下:

代码内容
// 增加文档时保存 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 时间。
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);
// 如果没有 stop words 去除还可以改成 TokenSources.getTokenStream(tpv,true); 进一步提速。
   TokenStream tokenStream=TokenSources.getTokenStream(tpv);
   //analyzer.tokenStream(FIELD_NAME,new StringReader(text));
   String result =
   highlighter.getBestFragments(
   tokenStream,
   text,
   maxNumFragmentsRequired, 
       fragmentSeparator);
   System.out.println(" " + result);
 }
}

最后把 highlight 包中的一个额外的判断去掉。对于中文来说没有明显的单词界限,所以下面这个判断是错误的:

tokenGroup.isDistinct(token)

这样中文分词就不会影响到查询速度了。
posted on 2006-02-20 14:30 TrampEagle 阅读(1200) 评论(0)  编辑  收藏 所属分类: opensource

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问