其他分享
首页 > 其他分享> > 使用通配符查询时的BooleanQuery $TooManyClauses异常

使用通配符查询时的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