2

我有一个包含 150 万个文档的 RAMDirectory,我正在使用 PrefixQuery 搜索单个字段。当搜索文本长度为 3 个或更多字符时,搜索速度极快,不到 20 毫秒。但是当搜索文本的长度少于 3 个字符时,搜索可能需要整整 1 秒。

由于它是一项自动完成功能,并且用户以一个字符开头(并且结果确实是 1 个字符长度),因此我无法限制搜索文本的长度。

代码差不多:

var symbolCodeTopDocs = searcher.Search(new PrefixQuery(new Term("SymbolCode", searchText), 10);

SymbolCode 是一个 NOT_ANALYZED 字段。Lucene.NET 版本是 3.0.3。

该示例已简化,我可能必须使用 BooleanQuery 在现实世界场景中应用额外的约束。

如何在这种特定情况下提高性能?这些单字符或双字符查询导致服务器停机。

4

1 回答 1

2

如果您还没有,请考虑从索引中删除停用词。

要了解停用词如何减慢 PrefixQuery 的速度,请考虑 PrefixQuery 的工作原理:它被重写为 BooleanQuery,其中包括索引中以 PrefixQuery 的术语开头的每个术语。例如a*变为a OR and OR aardvark OR anchor OR ...到目前为止,这还不错,即使有数千个术语,它也会表现得非常好。真正的消耗是当停用词喜欢aand被包含时,因为它们可能会在索引中的每个文档中多次找到。这为搜索的收集/收集/评分部分创造了更多的工作,从而减慢了速度。

附带说明一下,纯粹从可用性的角度来看,我强烈建议不要在用户输入少于 2 或 3 个字符时运行自动完成搜索。我无法想象结果会是完全相关的。想象一下运行搜索a*- 无法判断哪些结果更相关。如果您必须向用户显示某些内容,请考虑使用评论中建议的 Jf Beaulac 之类的 n-gram 方法。

于 2012-12-28T14:16:26.080 回答