package org.compass.core.lucene.engine.queryparser;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.payloads.BoostingTermQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.compass.core.engine.SearchEngineException;
import org.compass.core.engine.SearchEngineFactory;
import org.compass.core.lucene.engine.all.AllBoostingTermQuery;
import org.compass.core.mapping.ResourcePropertyLookup;
/**
* @author kimchy
*/
public abstract class QueryParserUtils {
private QueryParserUtils() {
}
/**
* Returns a poly alias query.
*/
public static Query createPolyAliasQuery(SearchEngineFactory searchEngineFactory, String value) {
BooleanQuery query = new BooleanQuery();
query.add(new TermQuery(new Term(searchEngineFactory.getAliasProperty(), value)), BooleanClause.Occur.SHOULD);
query.add(new TermQuery(new Term(searchEngineFactory.getExtendedAliasProperty(), value)), BooleanClause.Occur.SHOULD);
return query;
}
/**
* If enabled and allowed, wraps the given query with a boolean query that adds a must match on the alias).
*/
public static Query andAliasQueryIfNeeded(Query query, ResourcePropertyLookup lookup, boolean addAliasQueryWithDotPath,
SearchEngineFactory searchEngineFactory) {
if (query == null) {
return query;
}
if (!addAliasQueryWithDotPath) {
return query;
}
if (lookup == null) {
return query;
}
String alias = lookup.getDotPathAlias();
if (alias == null) {
return query;
}
BooleanQuery booleanQuery = new BooleanQuery();
booleanQuery.add(query, BooleanClause.Occur.MUST);
BooleanQuery aliasQuery = new BooleanQuery();
aliasQuery.add(new TermQuery(new Term(searchEngineFactory.getAliasProperty(), alias)), BooleanClause.Occur.SHOULD);
aliasQuery.add(new TermQuery(new Term(searchEngineFactory.getExtendedAliasProperty(), alias)), BooleanClause.Occur.SHOULD);
aliasQuery.setMinimumNumberShouldMatch(1);
booleanQuery.add(aliasQuery, BooleanClause.Occur.MUST);
return booleanQuery;
}
public static interface QueryTermVisitor {
Term replaceTerm(Term term) throws SearchEngineException;
}
public static Query visit(Query query, QueryTermVisitor visitor) throws SearchEngineException {
if (query instanceof TermQuery) {
Query q = new TermQuery(visitor.replaceTerm(((TermQuery) query).getTerm()));
q.setBoost(query.getBoost());
return q;
}
if (query instanceof BoostingTermQuery) {
Query q = new BoostingTermQuery(visitor.replaceTerm(((SpanTermQuery) query).getTerm()));
q.setBoost(query.getBoost());
return q;
}
if (query instanceof AllBoostingTermQuery) {
Query q = new AllBoostingTermQuery(visitor.replaceTerm(((SpanTermQuery) query).getTerm()));
q.setBoost(query.getBoost());
return q;
}
if (query instanceof SpanTermQuery) {
Query q = new SpanTermQuery(visitor.replaceTerm(((SpanTermQuery) query).getTerm()));
q.setBoost(query.getBoost());
return q;
}
if (query instanceof PhraseQuery) {
PhraseQuery original = (PhraseQuery) query;
PhraseQuery replaced = new PhraseQuery();
replaced.setBoost(original.getBoost());
replaced.setSlop(original.getSlop());
Term[] terms = original.getTerms();
int[] positions = original.getPositions();
for (int i = 0; i < terms.length; i++) {
replaced.add(visitor.replaceTerm(terms[i]), positions[i]);
}
return replaced;
}
if (query instanceof BooleanQuery) {
BooleanQuery original = (BooleanQuery) query;
BooleanQuery replaced = new BooleanQuery(original.isCoordDisabled());
replaced.setBoost(original.getBoost());
replaced.setMinimumNumberShouldMatch(original.getMinimumNumberShouldMatch());
for (BooleanClause clause : original.getClauses()) {
replaced.add(visit(clause.getQuery(), visitor), clause.getOccur());
}
return replaced;
}
return query;
}
}