org.hibernate.search.query.dsl.impl.BooleanQueryBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-search-engine Show documentation
Show all versions of hibernate-search-engine Show documentation
Core of the Object/Lucene mapper, query engine and index management
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate.search.query.dsl.impl;
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery.Builder;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
import org.hibernate.search.exception.AssertionFailure;
import org.hibernate.search.query.dsl.BooleanJunction;
import org.hibernate.search.query.dsl.MustJunction;
import org.hibernate.search.util.logging.impl.Log;
import org.hibernate.search.util.logging.impl.LoggerFactory;
import java.lang.invoke.MethodHandles;
/**
* @author Emmanuel Bernard
*/
class BooleanQueryBuilder implements MustJunction {
private static final Log log = LoggerFactory.make( MethodHandles.lookup() );
private final List clauses;
private BooleanClause lastClause;
private final QueryCustomizer queryCustomizer;
private MinimumShouldMatchContextImpl minimumShouldMatchContext;
private int shouldClauseCount = 0;
BooleanQueryBuilder() {
clauses = new ArrayList( 5 );
queryCustomizer = new QueryCustomizer();
}
@Override
public BooleanJunction not() {
replaceLastMustWith( BooleanClause.Occur.MUST_NOT );
return this;
}
@Override
public BooleanJunction disableScoring() {
replaceLastMustWith( BooleanClause.Occur.FILTER );
return this;
}
private void replaceLastMustWith(Occur replacementOccur) {
if ( lastClause == null ) {
return;
}
if ( ! lastClause.getOccur().equals( BooleanClause.Occur.MUST ) ) {
throw new AssertionFailure( "Cannot negate or disable scoring on class: " + lastClause.getOccur() );
}
final int lastIndex = clauses.size() - 1;
clauses.set( lastIndex, new BooleanClause( lastClause.getQuery(), replacementOccur ) );
}
@Override
public BooleanJunction should(Query query) {
if ( query == null ) {
lastClause = null;
}
else {
lastClause = new BooleanClause( query, BooleanClause.Occur.SHOULD );
clauses.add( lastClause );
++shouldClauseCount;
}
return this;
}
@Override
public MustJunction must(Query query) {
if ( query == null ) {
lastClause = null;
}
else {
lastClause = new BooleanClause( query, BooleanClause.Occur.MUST );
clauses.add( lastClause );
}
return this;
}
@Override
public MustJunction boostedTo(float boost) {
queryCustomizer.boostedTo( boost );
return this;
}
@Override
public MustJunction withConstantScore() {
queryCustomizer.withConstantScore();
return this;
}
@Override
public MustJunction filteredBy(Query filter) {
queryCustomizer.filteredBy( filter );
return this;
}
@Override
public Query createQuery() {
final int nbrOfClauses = clauses.size();
if ( nbrOfClauses == 0 ) {
throw log.booleanQueryWithoutClauses();
}
Builder builder = new org.apache.lucene.search.BooleanQuery.Builder();
boolean allClausesAreMustNot = true;
for ( BooleanClause clause : clauses ) {
if ( clause.getOccur() != Occur.MUST_NOT ) {
allClausesAreMustNot = false;
}
builder.add( clause );
}
if ( allClausesAreMustNot ) {
//It is illegal to have only must-not queries,
//in this case we need to add a positive clause to match everything else.
builder.add( new MatchAllDocsQuery(), Occur.FILTER );
}
if ( minimumShouldMatchContext != null ) {
minimumShouldMatchContext.applyMinimum( builder, shouldClauseCount );
}
return queryCustomizer.setWrappedQuery( builder.build() ).createQuery();
}
@Override
public boolean isEmpty() {
return clauses.isEmpty();
}
@Override
public BooleanJunction minimumShouldMatchNumber(int matchingClausesNumber) {
getMinimumShouldMatchContext().requireNumber( matchingClausesNumber );
return this;
}
@Override
public BooleanJunction minimumShouldMatchPercent(int matchingClausesPercent) {
getMinimumShouldMatchContext().requirePercent( matchingClausesPercent );
return this;
}
private MinimumShouldMatchContextImpl getMinimumShouldMatchContext() {
if ( minimumShouldMatchContext == null ) {
minimumShouldMatchContext = new MinimumShouldMatchContextImpl();
}
return minimumShouldMatchContext;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy