使用卢塞恩:如果进行前缀搜索,为什么会出现 Too Many Clauses 错误?
题
我已经有一个应用程序进行前缀搜索一段时间了。最近索引大小增加了,结果发现一些前缀太多了,Lucene 无法处理。它不断地向我抛出 条款太多 错误,这非常令人沮丧,因为我一直在查看 JAR 并确认所包含的代码实际上没有使用布尔查询。
为什么它不抛出“Too Many Hits”异常之类的异常?当我肯定只使用前缀查询时,为什么增加布尔查询的静态最大子句整数实际上会使此错误消失?是否存在我不理解的查询运行方式的基本原理?是不是它们偷偷地变成了布尔查询?
解决方案
我以前打过这个。这与以下事实有关:当您调用 Query.rewrite() 时,lucene 在幕后将许多(全部?)事物转换为布尔查询
public Query rewrite(IndexReader reader)
throws IOException
Expert: called to re-write queries into primitive queries.
For example, a PrefixQuery will be rewritten into a
BooleanQuery that consists of TermQuerys.
Throws:
IOException
其他提示
TooManyClauses 的 API 参考页显示 PrefixQuery、FuzzyQuery、WildcardQuery 和 RangeQuery 都是以这种方式扩展的(扩展为 BooleanQuery)。既然是在API参考中,那么它应该是用户可以依赖的行为。Lucene 不会对命中数设置任意限制(文档 ID 为 int 除外),因此“命中次数过多”异常可能没有意义。也许 PrefixQuery.rewrite(IndexReader) 应该捕获 TooManyClauses 并抛出“前缀太多”异常,但现在它的行为并非如此。
顺便说一下,另一种按前缀搜索的方法是使用 PrefixFilter。使用它过滤查询或使用 ConstantScoreQuery 包装过滤器。
当运行前缀查询时,Lucene 会在其“字典”中搜索与查询匹配的所有术语。如果超过 1024 个(默认情况下)匹配,则抛出 TooManyClauses-Exception。
您可以调用 BooleanQuery.setMaxClauseCount 来增加每个 BooleanQuery 允许的最大子句数。