0

我使用 Lucene.Net 在 C# 中构建了一个搜索/浏览应用程序的原型。源数据是一个中等大小的 5MB XML 文件(包含大约 900 个“文档”),我使用 Lucene 对其进行索引。我的搜索工作正常并且速度非常快。对于这个应用程序,浏览和查看每个“命中”文档很重要,因此用户可以选择一个命中并查看该文档的完整视图(通常适合一半屏幕),我需要在其中突出显示的匹配搜索词看法。我正在使用 WPF 和 MVVM 方法。文档视图当前使用十几个 ContentControls 实现,其中六个用于显示使用 highlightConverter 的可搜索字段。

性能很差,所以我添加了秒表计时来隔离问题。我的模型中的 HighlightSearchTerms 方法似乎是罪魁祸首(大约需要 100-600 毫秒来执行)。如果我将此方法短路以仅返回输入文本,则性能很好。

这是方法:

_analyzer is a StandardAnalyzer(_luceneVersion)
_parser is a QueryParser(_luceneVersion, “content”, _analyzer)
_formatter is a SimpleHTMLFormatter(“|~S~|”, “|~E~|”);

private string HighlightSearchTerms(string text, string queryString)
{
    var query = new BooleanQuery();
    query.Add(_parser.Parse(queryString), Occur.SHOULD);
    var fragmentScorer = new QueryScorer(query);
    var highlighter = new Highlighter(_formatter, fragmentScorer);
    highlighter.TextFragmenter = new NullFragmenter();
    var tokenStream = _analyzer.TokenStream(null, new StringReader(text));
    string highlightedText = highlighter.GetBestFragment(tokenStream, text);
    return highlightedText == null ? text : highlightedText;
}

几年前,我阅读了“Lucene In Action”一书,并再次翻阅了相关部分,看看我是否能得到任何想法。我也在网上搜索了很多。因此,这里有几个问题或可能探索的领域。

  1. 我可以以某种方式省略得分吗?我不需要显示匹配搜索词的上下文,因此我不需要将命中文档分解为片段并为各种片段获取“分数”。我想要按标题显示的命中列表,然后当用户选择一个命中时,整个命中文档都会突出显示。我看到如何使用 NullFragmenter 和 GetBestFragment,但我不知道这是否会使评分操作短路。省略评分会提高性能吗?
  2. 我已经考虑重构我的视图,使其具有一个小部件,用于将命中文档显示为一个 HTML 或 RTF 文本块。这样,我可以只调用一次 highlight 方法,而不是 10 或 15 次(一些 ContentControls 在 ItemsControl 内,因此视图上有一些字段的多个实例)。我预计这将显着提高性能。突出显示将在用表格格式等标记的文本上,但我想这仍然有效?
  3. 还有什么我遗漏的东西使我的突出显示方法如此缓慢吗?半秒似乎太慢了——就像我真的把一些基本的东西搞砸了一样。
4

1 回答 1

0

根据我在这里给出的答案,您可以获得额外的改进。

于 2016-07-05T23:21:34.303 回答