使用通配符查询时的BooleanQuery $TooManyClauses异常
作者:互联网
我正在使用Hibernate Search / Lucene来维护一个非常简单的索引,以按名称查找对象-没有花哨的东西.
我的模型类都扩展了一个NamedModel类,该类基本上如下所示:
@MappedSuperclass
public abstract class NamedModel {
@Column(unique = true)
@Field(store = Store.YES, index = Index.UN_TOKENIZED)
protected String name;
}
我的问题是,当查询索引中名称以特定字母开头的对象时,例如在BooleanQuery $TooManyClauses中出现异常. “名称:l *”.
诸如“ name:lin *”之类的查询将毫无问题地工作,实际上,任何使用通配符之前使用多个字母的查询都将起作用.
在网上搜索类似问题时,我只发现人们在使用非常复杂的查询,而且这似乎总是导致异常.我不想增加maxClauseCount,因为我不认为仅因为达到限制而改变限制是一个好习惯.
这是什么问题
解决方法:
Lucene尝试将您的查询从简单的name:l *重写为所有以l开头的所有术语的查询(类似于name:lou或name:la OR name:…)-我认为这样做的目的是为了更快.
解决方法是,可以使用ConstantScorePrefixQuery而不是PrefixQuery:
// instead of new PrefixQuery(prefix)
new ConstantScoreQuery(new PrefixFilter(prefix));
但是,这会更改文档的评分(如果您依靠得分进行排序,则可以进行排序).当我们面临需要得分(和提高)的挑战时,我们决定寻求一个解决方案,在可能的情况下使用PrefixQuery并在需要时回退到ConstantScorePrefixQuery:
new PrefixQuery(prefix) {
public Query rewrite(final IndexReader reader) throws IOException {
try {
return super.rewrite(reader);
} catch (final TooManyClauses e) {
log.debug("falling back to ConstantScoreQuery for prefix " + prefix + " (" + e + ")");
final Query q = new ConstantScoreQuery(new PrefixFilter(prefix));
q.setBoost(getBoost());
return q;
}
}
};
(作为一项增强功能,可以使用某种LRUMap缓存失败之前的术语,以避免再次进行昂贵的重写)
不过,我无法帮助您将其集成到Hibernate Search中.切换到Compass后,您可能会问;)
标签:hibernate-search,exception,java 来源: https://codeday.me/bug/20191210/2101833.html