Featured Image with Sidebar

How to use Facets to categorize your FullTextQuery results

By Thorben Janssen

Query

Facetting is another interesting feature provided by Hibernate Search. It allows you to group your FullTextQuery results in categories. You often see this in online shops which present the search results in different product categories or on websites which categorize their articles by date.

This is the 3rd post in my series about Hibernate Search, and it requires some basic knowledge about the full-text search framework. You should have a look at the 2 previous posts if you have no experience with Hibernate Search:

Prepare your entities for a faceted search

Before you can define a faceted search query, you need to prepare your search index for it. You can do that by annotating the entity attribute you want to use for faceting with a @Facet annotation. I did that with the userName attribute of my Tweet entity.

As you can see in the code snippet, I also annotated the userName attribute with @Field(analyze = Analyze.NO)). That is also required if you want to use an entity attribute for faceting. It’s obvious that you need to index an attribute that you want to use in a full-text query. But it’s not that obvious that you’re not allowed to apply any Analyzer to that field. If you want to analyze an attribute to use advanced full-text search features, like the ones I showed you in the previous post, you need to index it twice. You can simply do that by adding 2 @Field annotations to the entity attribute. One with the Analyzer and another one without it. You can then use the analyzed index for your full-text query and the not-analyzed index for the faceting.

Get faceted results

After you annotated an entity attribute with @Facet, you can use it in a FacetingRequest.

In the first step, you need to create a FullTextQuery for which you to get faceted results. I explained this part in more details in the first post of this series. The FullTextQuery in this example selects all Tweet entities from the Lucene index.

You can then use this query to with a FacetingRequest to get the different facets and their number of elements.

I first use the QueryBuilder to create a new FacetingRequest with the name “userNameFR” that uses the index field that maps the userName attribute. In this example, I want to get a maximum of 3 discrete facets which have at least 1 element that matches the full-text query.

By default, Hibernate Search returns the facets in the descending order of their search results.

Use a Facet in your query

Getting the facets of a query result and showing them in the UI is good first step. But what happens if you a user selects one of the facets and wants to see the matching query results?

You obviously need to use the selected facet in your query. You can do that based on the facets you selected in the previous example.

As you can see, you just need to get a FacetSelection from the FacetManager, select the Facet you want to use in your query and execute the FullTextQuery again.

Summar

As you’ve seen, Hibernate Search allows you to categorize the results of a FullTextQuery with Facets. That is a concept you often see in online shops which present the search results in different product categories or on websites which categorize their articles by date.

Facetting your query results with Hibernate Search requires 3 step:

    1. Add @Facet annotation to the entity attribute you want to use for facetting.
    2. Create a FullTextQuery.
    3. Create a FacetingRequest and retrieve the Facets.

After you retrieved all Facets, you can use one of them in your FullTextQuery.

About the author

Thorben is an independent consultant, international speaker, and trainer specialized in solving Java persistence problems with JPA and Hibernate.
He is also the author of Amazon’s bestselling book Hibernate Tips - More than 70 solutions to common Hibernate problems.

Books and Courses

Coaching and Consulting

Leave a Reply

Your email address will not be published. Required fields are marked

This site uses Akismet to reduce spam. Learn how your comment data is processed.

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}