BooleanQuery $ TooManyClauses exception when using wildcard queries

I use Hibernate Search / Lucene to maintain a really simple index to search for objects by name - no fancy stuff.

My model classes extend the class NamedModel, which looks basically like this:

@MappedSuperclass
public abstract class NamedModel {
    @Column(unique = true)
    @Field(store = Store.YES, index = Index.UN_TOKENIZED)
    protected String name;
}

My problem is that I get an exception BooleanQuery$TooManyClauseswhen querying the index for objects with names starting with a certain letter, for example. "name:l*". A type request "name:lin*"will work without problems, in fact, any request that uses more than one letter in front of the template will work.

When searching the web for similar problems, I found people using fairly complex queries and who always threw an exception. I don’t want to increase maxClauseCount, because I don’t think it’s good practice to change limits just because you reach them.

What is the problem?

+3
source share
1 answer

Lucene is trying to rewrite your query from simple name:l*to query with all terms starting with l in them (something like name:lou OR name:la OR name: ...). I believe it should be faster.

As a workaround, you can use ConstantScorePrefixQueryinstead 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;)

+3

Source: https://habr.com/ru/post/1720157/


All Articles