Lucene中文分词的highlight显示
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("\t" + result); } } 最后把highlight包中的一个额外的判断去掉。对于中文来说没有明显的单词界限,所以下面这个判断是错误的:tokenGroup.isDistinct(token) 这样中文分词就不会影响到查询速度了。 适合lucene-core-2.0.0.jar使用的highlighter.jar
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("\t" + result); } } 最后把highlight包中的一个额外的判断去掉。对于中文来说没有明显的单词界限,所以下面这个判断是错误的:tokenGroup.isDistinct(token) 这样中文分词就不会影响到查询速度了。 适合lucene-core-2.0.0.jar使用的highlighter.jar
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货