Created
March 14, 2011 13:57
-
-
Save emmanuelbernard/869143 to your computer and use it in GitHub Desktop.
Version with existing API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author Emmanuel Bernard <emmanuel@hibernate.org> | |
*/ | |
public class SearchService { | |
@Inject | |
FullTextEntityManager em; | |
private org.hibernate.search.FullTextQuery ftQuery; | |
private Map<FacetResult, OrFacetFilter> filtersByFacetResult = new HashMap<FacetResult, OrFacetFilter>(); | |
/** | |
* do the initial query | |
*/ | |
public List<Car> searchCar(String queryString) { | |
final QueryBuilder builder = em.getSearchFactory().buildQueryBuilder().forEntity( Car.class ).get(); | |
final Query query = builder.bool() | |
.should( builder.keyword().onField( "model" ).matching( queryString ).createQuery() ) | |
.should( builder.keyword().onField( "make" ).matching( queryString ).createQuery() ) | |
.createQuery(); | |
final FacetRequest colorFacet = builder.facet().name( "color" ).onField( "color" ).discrete().createFacet(); | |
final FacetRequest priceFacet = builder.facet().name( "price" ).onField( "color" ) | |
.range() | |
.from( 0 ).to( 5000 ).excludeLimit() | |
.from( 5000 ).to( 15000 ).excludeLimit() | |
.from( 15000 ).to( Integer.MAX_VALUE ) //fix with .above(15000) | |
.createFacet(); | |
//FIXME jpa.FTQuery does not have the facet methods, need to do some nasty unwrapping | |
ftQuery = em.unwrap( FullTextSession.class ) | |
.createFullTextQuery( query, Car.class ); | |
ftQuery.setFirstResult( 0 ).setMaxResults( 20 ); | |
ftQuery.enableFacet( colorFacet ).enableFacet( priceFacet ); | |
final List results = ftQuery.list(); | |
return results; | |
} | |
/** | |
* Simulate display of facets on the left side (like Amazon) | |
*/ | |
public void displayFacets() { | |
StringBuilder sb = new StringBuilder(); | |
for ( FacetResult facetResult : ftQuery.getFacetResults().values() ) { | |
sb.append( facetResult.getName() ).append( "\n" ); | |
//TODO should the index be included in object Facet? Not sure but worth thinking about | |
for ( int index = 0; index < facetResult.getFacets().size(); index++ ) { | |
Facet facet = facetResult.getFacets().get( index ); | |
final boolean facetSelected = filtersByFacetResult.get( facetResult ).getFacets().contains( facet ); | |
sb.append( "\t" ); | |
if ( facetSelected ) { | |
sb.append( "[UNSELECT]" ); | |
} | |
else { | |
sb.append( "[SELECT]" ); | |
} | |
sb.append( facet.getValue() ).append( " (" ).append( facet.getCount() ).append( ")" ) | |
.append( " hidden index: " ).append( index ); | |
} | |
} | |
} | |
/** | |
* method called on a click to a discrete facet. discrete facets are usually multiselectable (like Amazon) | |
*/ | |
public List<Car> selectOrDeselectFacetFilterAndReturnResults(String facetName, int element) { | |
final FacetResult facetResult = ftQuery.getFacetResults().get( facetName ); | |
final Facet facet = facetResult.getFacets().get( element ); | |
OrFacetFilter filter = filtersByFacetResult.get( facetResult ); | |
if ( filter == null ) { | |
//FIXME need the notion of OrFacetFilter to apply a logical Or on Filter results | |
filter = new OrFacetFilter(); | |
filtersByFacetResult.put( facetResult, filter ); | |
} | |
if ( filter.getFacets().contains( facet ) ) { | |
filter.removeFacet( facet ); | |
} | |
else { | |
filter.addFacet( facet ); | |
} | |
AndFilter globalFilter = new AndFilter(); | |
for ( OrFacetFilter orFilter : filtersByFacetResult.values() ) { | |
globalFilter.add( orFilter ); | |
} | |
ftQuery.setFilter( globalFilter ); | |
final List results = ftQuery.list(); | |
return results; | |
} | |
private class OrFacetFilter extends Filter { | |
@Override | |
public DocIdSet getDocIdSet(IndexReader indexReader) throws IOException { | |
return null; | |
} | |
public void addFacet(Facet facet) { | |
//TODO | |
} | |
public void removeFacet(Facet facet) { | |
//TODO | |
} | |
public Set<Facet> getFacets() { | |
return null; //TODO | |
} | |
} | |
private class AndFilter extends Filter { | |
public void add(Filter f) { | |
//TODO | |
} | |
@Override | |
public DocIdSet getDocIdSet(IndexReader indexReader) throws IOException { | |
return null; //TODO | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment