tags:

views:

873

answers:

1

In my tests I suddenly bumped into a Too Many Clauses exception when trying to get the hits from a boolean query that consisted of a termquery and a wildcard query.

I searched around the net and on the found resources they suggest to increase the BooleanQuery.SetMaxClauseCount().
This sounds fishy to me.. To what should I up it? How can I rely that this new magic number will be sufficient for my query? How far can I increment this number before all hell breaks loose?

In general I feel this is not a solution. There must be a deeper problem..

The query was +{+companyName:mercedes +paintCode:a*} and the index has ~2.5M documents.

A: 

the paintCode:a* part of the query is a prefix query for any paintCode beginning with an "a". Is that what you're aiming for?

Lucene expands prefix queries into a boolean query containing all the possible terms that match the prefix. In your case, apparently there are more than 1024 possible paintCodes that begin with an "a".

If it sounds to you like prefix queries are useless, you're not far from the truth.

I would suggest you change your indexing scheme to avoid using a Prefix Query. I'm not sure what you're trying to accomplish with your example, but if you want to search for paint codes by first letter, make a paintCodeFirstLetter field and search by that field.

ADDED

If you're desperate, and are willing to accept partial results, you can build your own Lucene version from source. You need to make changes to the files PrefixQuery.java and MultiTermQuery.java, both under org/apache/lucene/search. In the rewrite method of both classes, change the line

query.add(tq, BooleanClause.Occur.SHOULD);          // add to query

to

try {
    query.add(tq, BooleanClause.Occur.SHOULD);          // add to query
} catch (TooManyClauses e) {
    break;
}

I did this for my own project and it works.

If you really don't like the idea of changing Lucene, you could write your own PrefixQuery variant and your own QueryParser, but I don't think it's much better.

itsadok
It's the backend for an autocomplete dropdown. Isn't there a way to make it just return the results it's already found?
borisCallens
Hmm, so no default options there then.. That's kind of o downer. Thanks for the response.
borisCallens
For an auto-complete field, why not use the terms enumerations returned from the index reader and maintain your own cached list? You'll need to check the index reader every now and then to refresh the list, but at least you'll have complete flexibility...
Moleski
Well, actually, that's not that bad an idea.. A bit stupid to distribute my searching over both Lucene and my own filtering, but it's the best thing I can think of now.
borisCallens