com.browseengine.bobo.search.section.SectionSearchQueryPlanBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bobo-browse Show documentation
Show all versions of bobo-browse Show documentation
Bobo is a Faceted Search implementation written purely in Java, an extension of Apache Lucene
The newest version!
/**
*
*/
package com.browseengine.bobo.search.section;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.lucene.index.AtomicReader;
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;
/**
*
*/
public class SectionSearchQueryPlanBuilder {
public static class TranslationException extends RuntimeException {
private static final long serialVersionUID = 1L;
public TranslationException(String message) {
super(message);
}
}
protected final AtomicReader _reader;
protected final MetaDataCacheProvider _cacheProvider;
public SectionSearchQueryPlanBuilder(AtomicReader reader) {
_reader = reader;
_cacheProvider = (reader instanceof MetaDataCacheProvider ? (MetaDataCacheProvider) reader
: null);
}
/**
* Gets a query plan for the given query.
* It is assumed that query
is already rewritten before this call.
* @param query
* @return SectionSearchQueryPlan
* @throws IOException
*/
public SectionSearchQueryPlan getPlan(Query query) throws IOException {
if (query != null) {
SectionSearchQueryPlan textSearchPlan = translate(query);
if (!(textSearchPlan instanceof UnaryNotNode)) {
return textSearchPlan;
}
}
return null;
}
/**
* Translates a Lucence Query object to an SectionSearchQueryPlan
* @param query
* @param reader
* @return
* @throws IOException
*/
private SectionSearchQueryPlan translate(Query query) throws IOException {
if (query != null) {
if (query instanceof TermQuery) {
return translateTermQuery((TermQuery) query);
} else if (query instanceof PhraseQuery) {
return translatePhraseQuery((PhraseQuery) query);
} else if (query instanceof BooleanQuery) {
return translateBooleanQuery((BooleanQuery) query);
} else if (query instanceof MetaDataQuery) {
MetaDataQuery mquery = (MetaDataQuery) query;
MetaDataCache cache = (_cacheProvider != null ? _cacheProvider.get(mquery.getTerm()) : null);
if (cache != null) {
return ((MetaDataQuery) query).getPlan(cache);
} else {
return ((MetaDataQuery) query).getPlan(_reader);
}
} else {
throw new TranslationException("unable to translate Query class: "
+ query.getClass().getName());
}
}
return null;
}
private SectionSearchQueryPlan translateTermQuery(TermQuery query) throws IOException {
return new TermNode(query.getTerm(), _reader);
}
private SectionSearchQueryPlan translatePhraseQuery(PhraseQuery query) throws IOException {
Term[] terms = query.getTerms();
TermNode[] nodes = new TermNode[terms.length];
int[] positions = query.getPositions();
for (int i = 0; i < terms.length; i++) {
nodes[i] = new TermNode(terms[i], positions[i], _reader);
}
return new PhraseNode(nodes, _reader);
}
private SectionSearchQueryPlan translateBooleanQuery(BooleanQuery query) throws IOException {
ArrayList requiredClauses = new ArrayList();
ArrayList prohibitedClauses = new ArrayList();
ArrayList optionalClauses = new ArrayList();
BooleanClause[] clauses = query.getClauses();
for (BooleanClause clause : clauses) {
if (clause.isRequired()) {
requiredClauses.add(clause.getQuery());
} else if (clause.isProhibited()) {
prohibitedClauses.add(clause.getQuery());
} else {
optionalClauses.add(clause.getQuery());
}
}
SectionSearchQueryPlan positiveNode = null;
SectionSearchQueryPlan negativeNode = null;
if (requiredClauses.size() > 0) {
if (requiredClauses.size() == 1) {
positiveNode = translate(requiredClauses.get(0));
} else {
SectionSearchQueryPlan[] subqueries = translate(requiredClauses);
if (subqueries != null && subqueries.length > 0) positiveNode = new AndNode(subqueries);
}
} else if (optionalClauses.size() > 0) {
if (optionalClauses.size() == 1) {
positiveNode = translate(optionalClauses.get(0));
} else {
SectionSearchQueryPlan[] subqueries = translate(optionalClauses);
if (subqueries != null && subqueries.length > 0) positiveNode = new OrNode(subqueries);
}
}
if (prohibitedClauses.size() > 0) {
if (prohibitedClauses.size() == 1) {
negativeNode = translate(prohibitedClauses.get(0));
} else {
negativeNode = new OrNode(translate(prohibitedClauses));
}
}
if (negativeNode == null) {
return positiveNode;
} else {
if (positiveNode == null) {
return new UnaryNotNode(negativeNode);
} else {
return new AndNotNode(positiveNode, negativeNode);
}
}
}
private SectionSearchQueryPlan[] translate(ArrayList queries) throws IOException {
int size = queries.size();
ArrayList result = new ArrayList(size);
for (int i = 0; i < size; i++) {
SectionSearchQueryPlan plan = translate(queries.get(i));
if (plan != null) result.add(plan);
}
return result.toArray(new SectionSearchQueryPlan[result.size()]);
}
}