使用Lucene:如果我进行前缀搜索,为什么会出现太多子句错误?

时间:2020-03-05 18:39:06  来源:igfitidea点击:

我有一个应用程序做了一段时间的前缀搜索。最近,索引的大小增加了,结果发现某些前缀太繁杂,以至于Lucene无法处理。它一直向我抛出"太多子句"错误,当我不断查看我的JAR并确认所包含的代码中没有一个实际上使用布尔查询时,这非常令人沮丧。

为什么它不引发" Tooth Many Hits"之类的异常呢?不会。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。当我绝对只使用前缀查询时,为什么增加布尔查询的静态max子句整数实际上会使此错误消失呢?我不了解查询的运行方式是否存在一些基本问题;是他们秘密地成为布尔查询吗?

解决方案

回答

我以前打过这与以下事实有关:在调用Query.rewrite()时,lucene在幕后将许多(全部?)内容转换为布尔查询。

来自:http://lucene.apache.org/java/2_2_0/api/org/apache/lucene/search/Query.html#rewrite(org.apache.lucene.index.IndexReader)

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

回答

运行前缀查询时,Lucene会在其"词典"中搜索与查询匹配的所有术语。如果超过1024个(默认情况下)匹配,则抛出TooManyClauses-Exception。

我们可以调用BooleanQuery.setMaxClauseCount来增加每个BooleanQuery允许的最大子句数。

回答

TooManyClauses的API参考页显示,PrefixQuery,FuzzyQuery,WildcardQuery和RangeQuery以这种方式扩展(转换为BooleanQuery)。由于它在API参考中,因此它应该是用户可以依赖的行为。 Lucene不会对命中次数设置任何限制(文档ID为int除外),因此"太多命中"异常可能没有意义。也许PrefixQuery.rewrite(IndexReader)应该捕获TooManyClauses并抛出"前缀太多"异常,但是现在它的行为并不如此。

顺便说一句,按前缀搜索的另一种方法是使用PrefixFilter。或者用它过滤查询,或者用ConstantScoreQuery包裹过滤器。