Introduction to hibernate search faceting
With the document available from Hibernate Search (https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#query-facetin...
https://www.czetsuyatech.com/2017/10/hibernate-search-faceting.html
With the document available from Hibernate Search (https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#query-faceting), 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?
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?
- Annotate Author.id with @facet.
@Facets({ @Facet, @Facet(name = "id_facet", forField = "id_for_facet", encoding = FacetEncodingType.STRING) }) @Fields({ @Field(name = "id_for_facet", analyze = Analyze.NO, bridge = @FieldBridge(impl = org.hibernate.search.bridge.builtin.IntegerBridge.class)) }) @Id @Column(name = "id") @GeneratedValue private Integer id;
- 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; } @Override public String getFacetingName() { return delegate.getFacetingName(); } @Override public String getFieldName() { return delegate.getFieldName(); } @Override public String getValue() { return delegate.getValue(); } @Override public int getCount() { return delegate.getCount(); } @Override public Query getFacetQuery() { return delegate.getFacetQuery(); } public T getEntity() { return entity; } @Override public String toString() { return "EntityFacet [delegate=" + delegate + ", entity=" + entity + "]"; } } - 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(); org.apache.lucene.search.Query 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() .orderedBy(FacetSortOrder.COUNT_DESC).includeZeroCounts(false).maxFacetCount(5).createFacetingRequest(); // retrieve facet manager and apply faceting request FacetManager facetManager = fullTextQuery.getFacetManager(); facetManager.enableFaceting(authorFacet); // retrieve the faceting results List<Facet> facets = facetManager.getFacets("authorIdFacet"); // collect all the ids List<Integer> vcIds = facets.stream().map(p -> 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))); } entityFacets.stream().forEach(System.out::println);
For code reference you may check this repository: https://github.com/czetsuya/hibernate-search-demo
Got a question? Don't hesitate to ask :-)
Post a Comment