/*
* Copyright (c) 2009 Andrejs Jermakovics.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrejs Jermakovics - initial implementation
*/
package it.unibz.instasearch.indexing.querying;
import it.unibz.instasearch.indexing.Field;
import java.util.Map;
import java.util.Set;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
/**
*
*/
public class FilterSetter extends QueryVisitor {
private Map<Field, Set<String>> filter;
public FilterSetter() {
}
@Override
public Query visit(TermQuery termQuery, Field field) {
return addFilters(termQuery, field);
}
@Override
public Query visit(PrefixQuery originalQuery, Field field) {
return addFilters(originalQuery, field);
}
@Override
public Query visit(WildcardQuery wildcardQuery, Field field) {
return addFilters(wildcardQuery, field);
}
private Query getFilterQuery(Query originalQuery, Field field, Set<String> values)
{
BooleanQuery boolQuery = new BooleanQuery();
if( originalQuery != null )
{
boolQuery.add(originalQuery, Occur.SHOULD); // original term
boolQuery.setBoost( originalQuery.getBoost() );
}
for(String value: values)
boolQuery.add(new TermQuery(field.createTerm(value)), Occur.SHOULD);
return boolQuery;
}
private Query addFilters(Query originalQuery, Field field)
{
Set<String> values = filter.get(field);
if( values != null )
{
filter.remove(field);
return getFilterQuery(originalQuery, field, values);
}
return originalQuery;
}
@Override
public Query endVisit(Query query)
{
if( filter.isEmpty() )
return super.endVisit(query);
// combine filters with main query using AND
BooleanQuery conjQuery = new BooleanQuery();
conjQuery.add(query, Occur.MUST);
for(Field field: filter.keySet())
{
Set<String> values = filter.get(field); // possible values
if( values.size() == 1 )
{
String value = values.iterator().next();
conjQuery.add( new TermQuery(field.createTerm(value)), Occur.MUST);
}
else // several values, any of them should match (using OR here)
{
conjQuery.add( getFilterQuery(null, field, values), Occur.MUST);
}
}
return conjQuery;
}
/**
* @param filter
*/
public void setFilter(Map<Field, Set<String>> filter) {
this.filter = filter;
}
}