Lucene Hightlighter有时会莫名其妙地返回空白片段

在过去的几天里,我一直在研究Lucene文档搜索程序,到目前为止,一切都进展顺利。 我正在尝试使用Lucene.Net.Highlight.Highlighter类来显示搜索结果的相关片段,但它不能始终如一地工作。 大多数情况下,调用Highlighter.GetBestFragments()完全符合我的预期(显示其中包含给定查询字符串的相关文本片段),但有时它只返回一个空字符串。

我已经三次检查我的输入,我可以validation我正在使用的查询字符串是否存在于输入文本中,但是荧光笔有时会随意返回一个空字符串。 这个问题是可以重现的; 返回空白片段的文档在使用相同查询时将继续返回空白片段,而具有合法片段的文档将继续具有合法片段。

但是,问题不是特定于文档的。 某些查询返回文档的有效片段,其他查询返回同一文档的空字符串。 问题似乎也与我的分析仪无关; 问题出现在我是使用StandardAnalyzer还是SnowballAnalyzer

经过几个小时的探索,我无法在查询/文档中找到任何失败的模式,而不是那些有效的模式。 请记住,这是在使用完全相同的查询从Lucene索引中专门撤回的文档上发生的。 这意味着Searcher能够在目标文档中找到相关的查询字符串,但Highlighter不能。

这是Lucene的一个错误吗? 如果是这样,我该如何解决呢?

我的代码:

 private static SimpleHTMLFormatter _formatter = new SimpleHTMLFormatter("", ""); private static SimpleFragmenter _fragmenter = new SimpleFragmenter(50); ... { using (var searcher = new IndexSearcher(analyzerInfo.Directory, false)) { QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "Text", analyzerInfo.Analyzer); parser.SetMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE); //build query BooleanQuery booleanQuery = new BooleanQuery(); booleanQuery.Add(new TermQuery(new Term("PageNum", "0")), BooleanClause.Occur.MUST); booleanQuery.Add(parser.Parse(searchQuery), BooleanClause.Occur.MUST); Query query = booleanQuery.Rewrite(searcher.GetIndexReader()); //get results from query ScoreDoc[] hits = searcher.Search(query, 50).ScoreDocs; List results = hits.Select(hit => MapLuceneDocumentToData(searcher.Doc(hit.Doc))).ToList(); //add relevant fragments to search results (shows WHY a certain result was chosen) QueryScorer scorer = new QueryScorer(query); Highlighter highlighter = new Highlighter(_formatter, scorer); highlighter.SetTextFragmenter(_fragmenter); foreach (DVDoc result in results) { TokenStream stream = analyzerInfo.Analyzer.TokenStream("Text", new StringReader(result.Text)); result.RelevantFragments = highlighter.GetBestFragments(stream, result.Text, 3, "..."); } //clean up analyzerInfo.Analyzer.Close(); searcher.Close(); return results; } } 

(注意: DVDoc本质上只是一个结构,它存储有关找到的文档的信息。方法MapLuceneDocumentToData将Lucene Document转换为我的自定义DVDoc类,没有魔法。)

因为每个人都喜欢示例输入和输出:

  • GetBestFragments工作的示例
  • GetBestFragments示例不起作用

我正在使用Lucene.NET版本2.9.4g。

默认情况下,Highlighter将仅处理Document的前51200个字符。

要增加此限制,请设置MaxDocCharsToAnalyze属性。

http://lucene.apache.org/core/old_versioned_docs/versions/2_9_2/api/contrib-highlighter/org/apache/lucene/search/highlight/Highlighter.html#setMaxDocCharsToAnalyze(int)