How to implement a practical example of Hibernate Search Faceting

With the document available from Hibernate Search (

With the document available from Hibernate Search (, we should be able to implement a faceting example that returns the faceting field and its count. In the example from Hibernate Search, our entity is CD, we create a facet on label field, so it will group the CD by label, and count all of each occurrence. But what if we want more info like the artist, sales, etc.

Going back to the previous example from hibernate where we have the following entities (Book, Author, Review). Let's say we want to group the books by author, how should we achieve that?

  1. Annotate with @facet.
    @Facets({ @Facet, @Facet(name = "id_facet", forField = "id_for_facet", encoding = FacetEncodingType.STRING) })
    @Field(name = "id_for_facet", analyze = Analyze.NO, bridge = @FieldBridge(impl = })
    @Column(name = "id")
    private Integer id;
  2. Create a class that will hold the desired entity and the facet result.
    public class EntityFacet implements Facet {
     private final Facet delegate;
     private final T entity;
     public EntityFacet(Facet delegate, T entity) {
      this.delegate = delegate;
      this.entity = entity;
     public String getFacetingName() {
      return delegate.getFacetingName();
     public String getFieldName() {
      return delegate.getFieldName();
     public String getValue() {
      return delegate.getValue();
     public int getCount() {
      return delegate.getCount();
     public Query getFacetQuery() {
      return delegate.getFacetQuery();
     public T getEntity() {
      return entity;
     public String toString() {
      return "EntityFacet [delegate=" + delegate + ", entity=" + entity + "]";
  3. Let's query the facet and the entity that contains more of the information we want. In this case the author. Note that we need to add the faceted field in the includePaths property in the @IndexedEmbedded annotation of the main entity (Book), or don't specify a field so all annotated fields are included.
    FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
    QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Book.class).get(); luceneQuery = qb.all().createQuery();
    FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, Book.class);
    // define the facet
    FacetingRequest authorFacet = qb.facet().name("authorIdFacet").onField("authors.id_facet").discrete()
    // retrieve facet manager and apply faceting request
    FacetManager facetManager = fullTextQuery.getFacetManager();
    // retrieve the faceting results
    List<Facet> facets = facetManager.getFacets("authorIdFacet");
    // collect all the ids
    List<Integer> vcIds = -> Integer.parseInt(p.getValue())).collect(Collectors.toList());
    // query all the Authors given the id we faceted above, I think multiLoad has
    // been introduced in HS 5.x
    List<Author> authors = fullTextEntityManager.unwrap(Session.class).byMultipleIds(Author.class).multiLoad(vcIds);
    // fill our container object with the facet and author entity
    List<EntityFacet<Author>> entityFacets = new ArrayList<>(facets.size());
    for (int i = 0; i < facets.size(); i++) {
     entityFacets.add(new EntityFacet<Author>(facets.get(i), authors.get(i)));
For code reference you may check this repository:

Got a question? Don't hesitate to ask :-)


java 2279572274878094611

Post a Comment