Hibernate Search is a library that integrates Hibernate ORM with Apache Lucene or Elasticsearch by automatically indexing entities, enabling advanced search functionality: full-text, geospatial, aggregations and more. For more information, see Hibernate Search on hibernate.org.

Moving from Alpha1 to Beta1, I am happy to announce the release of Hibernate Search 3.4.0.Beta1. The release includes an upgrade to Hibernate Core 3.6.2 and the usual bug fixes (see Jira release notes for all the gory details).

The main focus, however, lies on the refinement of the faceting API. This time we even provide some documentation. There are three steps to the usage of the faceting API. First you create the faceting request itself. This is done via the QueryBuilder and the faceting DSL. At the moment we support discrete faceting and range faceting. Here are some examples based on the example entity Cd:

public class Cd {
    private int id;

    @Fields( {
        @Field(name = "name_un_analyzed", index = Index.UN_TOKENIZED)
    private String name;

    @Field(index = Index.UN_TOKENIZED)
    private int price;

    Field(index = Index.UN_TOKENIZED)
    @DateBridge(resolution = Resolution.YEAR)
    private Date releaseYear;

    @Field(index = Index.UN_TOKENIZED)
    private String label;

// setter/getter
Given the Cd entity, creating faceting request could look like this:
QueryBuilder builder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity( Cd.class ).get();
FacetingRequest labelFacetingRequest = builder.facet()
    .name( "labelFaceting" )
    .onField( "label")
    .orderedBy( FacetSortOrder.COUNT_DESC )
    .includeZeroCounts( false )
    .maxFacetCount( 10 )

FacetingRequest priceacetingRequest = queryBuilder( Cd.class ).facet()
    .name( "priceFaceting" )
    .onField( "price" )
    .below( 1000 )
    .from( 1001 ).to( 1500 )
    .above( 1500 ).excludeLimit()
As a second step you have to apply the created faceting request on a query. After executing the query, you can then access the faceting results. Both tasks are achieved via the FacetManager API:
// create a fulltext query
QueryBuilder builder = queryBuilder( Cd.class );
Query luceneQuery = builder.all().createQuery(); // match all query
FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery, clazz );

// retrieve facet manager and apply faceting request
FacetManager facetManager = query.getFacetManager();
facetManager.enableFaceting( priceFacetingRequest );

// get the list of Cds
List<Cd> cds = fullTextQuery.list();
assertTrue(cds.size() == 10);

// retrieve the faceting results
List<Facet> facets = facetManager.getFacets( "priceFaceting" );
assertTrue(facets.get(0).getCount() == 2)
Last but not least you can apply a given Facet onto the query itself using the FacetSelection interface. Once the additional criteria is applied you can re-execute the query and use the new result set and faceting results.
// everything as in the previous example

// apply first facet as additional search criteria
facetManager.getFacetGroup( "priceFaceting" ).selectFacets( facets.get( 0 ) );

// re-execute the query
cds = fullTextQuery.list();
assertTrue(cds.size() == 2);

// deselect the facet
facetManager.getFacetGroup( "priceFaceting" ).deselectFacets( facets.get( 0 ) );

// re-execute the query
cds = fullTextQuery.list();
assertTrue(cds.size() == 10);
We hope this faceting API covers most of the use cases while still nicely fitting into the overall Hibernate Search architecture, but of course we won't know until you provide us some feedback :-)

As always, download of the release is via the JBoss Maven Repository or via SourceForge. The documentation can be found here.


Back to top