package er.neo4jadaptor.query.lucene;
import org.apache.lucene.search.Query;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.index.IndexHits;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webobjects.eoaccess.EOEntity;
import com.webobjects.eocontrol.EOQualifier;
import er.neo4jadaptor.query.Filter;
import er.neo4jadaptor.query.Results;
import er.neo4jadaptor.query.lucene.results.LuceneIndexHits;
import er.neo4jadaptor.query.neo4j_eval.EvaluatingFilter;
import er.neo4jadaptor.storage.IndexProvider;
/**
* Gets result records from the Lucene index, but in case if it's not able to perform Lucene query
* matching exactly EO qualifier criterias (if Lucene search is more liberal than {@link EOQualifier}
* then it performs additionally {@link er.neo4jadaptor.query.neo4j_eval.EvaluatingFilter} on the results.
* This filter will return records exactly matching search criteria.
*
* @author Jedrzej Sobanski
*
* @param <Type>
*/
public class LuceneFilter <Type extends PropertyContainer> extends Filter<Type> {
private static final Logger log = LoggerFactory.getLogger(LuceneFilter.class);
public LuceneFilter() {
}
@Override
public Results<Type> doFilter(GraphDatabaseService db, EOEntity entity, EOQualifier qualifier) {
LuceneQueryConverter luceneConverter = new LuceneQueryConverter();
Query q = luceneConverter.fullQuery(entity, qualifier);
final Results<Type> objects;
Index<Type> index = (Index<Type>) IndexProvider.instance.getIndexForEntity(db, entity);
IndexHits<Type> hits = index.query(q);
log.debug("Querying lucene with {}.", q);
// optimization
if (LuceneOptimizer.canBeOptimized(hits, qualifier)) {
LuceneOptimizer<Type> optimizer = new LuceneOptimizer<>(index);
objects = optimizer.optimize(q, entity, qualifier);
} else {
objects = new LuceneIndexHits<>(hits);
}
if (luceneConverter.isQueryFullyCovered()) {
return objects;
} else {
return new EvaluatingFilter<>(objects, entity, qualifier);
}
}
}