我有一个应用程序进行前缀搜索一段时间。最近索引大小增加了,结果发现某些前缀太多,以至于 lucene 无法处理。它不断向我抛出一个Too Many Clauses错误,这让我非常沮丧,因为我一直在查看我的 JAR 并确认包含的代码实际上都没有使用布尔查询。
为什么它不抛出类似 Too Many Hits 异常的东西?当我肯定只使用前缀查询时,为什么增加布尔查询的静态最大子句整数实际上会使这个错误消失?查询的运行方式是否有一些我不理解的基本内容?是不是他们偷偷变成了布尔查询?
我有一个应用程序进行前缀搜索一段时间。最近索引大小增加了,结果发现某些前缀太多,以至于 lucene 无法处理。它不断向我抛出一个Too Many Clauses错误,这让我非常沮丧,因为我一直在查看我的 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 允许的最大子句数。