lucene BooleanQuery


Example

BooleanQuery is used to combine other queries.

They can be combined using three BooleanClause.Occur parameters:

  • BooleanClause.Occur.MUST - The subquery must be matched.
  • BooleanClause.Occur.SHOULD - The subquery may not be matched, but will be scored more highly if it is. If there are no MUST clauses, then at least one SHOULD clause must be matched.
  • BooleanClause.Occur.MUST_NOT - The subquery must not match the document.

In this example, a document will match if it has "important", but not "forbidden", and will get a higher score if it also has "helpful".

Query importantQuery = new TermQuery(new Term("fieldname", "important"));
Query optionalQuery = new TermQuery(new Term("fieldname", "helpful"));
Query forbidQuery = new TermQuery(new Term("fieldname", "forbidden"));
BooleanQuery query = new BooleanQuery.Builder()
        .add(importantQuery, BooleanClause.Occur.MUST) 
        .add(optionalQuery, BooleanClause.Occur.SHOULD) 
        .add(forbidQuery, BooleanClause.Occur.MUST_NOT) 
        .build();

Alternatively, you can also specify the minimum number of clauses that must be matched:

Query query1 = new TermQuery(new Term("fieldname", "one"));
Query query2 = new TermQuery(new Term("fieldname", "two"));
Query query3 = new TermQuery(new Term("fieldname", "three"));
BooleanQuery query = new BooleanQuery.Builder()
        .add(query1, BooleanClause.Occur.SHOULD) 
        .add(query2, BooleanClause.Occur.SHOULD) 
        .add(query3, BooleanClause.Occur.SHOULD)
        .setMinimumNumberShouldMatch(2)
        .build();

Gotcha: Clauses with BooleanClause.Occur.MUST_NOT do not match everything else, they only eliminate matches. Your BooleanQuery must have at least one MUST or SHOULD clause, or it will match nothing. This, for example, will NOT work:

//***This does NOT work!***
Query forbidQuery = new TermQuery(new Term("fieldname", "forbidden"));
BooleanQuery getEverythingElseQuery = new BooleanQuery.Builder()
        .add(forbidQuery, BooleanClause.Occur.MUST_NOT) 
        .build();