Boosting search result relevance

We have already seen that the default sort order for search results is by relevance, meaning the degree to which they match the query. If one entity matches on two fields, while another has only one field match, then that first entity is the more relevant result.

Hibernate Search allows us to adjust how relevance is calculated, by boosting the relative importance of entities or fields when they are indexed. These adjustments can be static and fixed, or they can be dynamic and driven by the state of the data at runtime.

Static boosting at index-time

Fixed boosting, regardless of the actual data, is as simple as annotating a class or field with @Boost. This annotation takes a floating-point parameter for its relative weight, with the default weight being 1.0. So for example, @Boost(2.0f) would double the weight of a class or field relative to non-annotated classes and fields.

Our VAPORware Marketplace application searches on several fields and associations, such as the names of supported devices, and comments posted in customer reviews. However, doesn't it make sense that the text under our control (each app's name and full description) should carry more weight than text coming from outside parties?

To make this adjustment, the chapter4 version starts by annotating the App class itself:

...
@Boost(2.0f)
public class App implements Serializable {
...

This essentially makes App twice as relevant as Device or CustomerReview. Next, we apply field-level boosting to the name and full description fields:

...
@Boost(1.5f)
private String name;
...
@Boost(1.2f)
private String description;
...

We are declaring here that name carries slightly more weight than description, and they each carry more weight relative to normal fields.

Note

Be aware that class-level and field-level boosting cascade and combine! When more than one boost factor applies to a given field, they are multiplied to form the total factor.

Here, because a weight of 2.0 was already applied to the App class itself, name has a total effective weight of 3.0 and description is at 2.4.

Dynamic boosting at index-time

For an example of boosting an entity dynamically based on its data at index-time, let's say that we wanted to give the CustomerReview objects a bit more weight when the reviewer gives a five-star rating. To do this, we apply a @DynamicBoost annotation to the class:

...
@DynamicBoost(impl=FiveStarBoostStrategy.class)
public class CustomerReview {
...

This annotation must be passed a class that implements the BoostStrategy interface, and its defineBoost method:

public class FiveStarBoostStrategy implements BoostStrategy {

   public float defineBoost(Object value) {
      if(value == null || !(value instanceofCustomerReview)) {
         return 1;
      }
      CustomerReviewcustomerReview = (CustomerReview) value;
      if(customerReview.getStars() == 5) {
         return 1.5f;
      } else {
         return 1;
      }
   }

}

When the @DynamicBoost annotation was applied to a class, the parameter automatically passed to defineBoost is an instance of that class (a CustomerReview object in this case). If the annotation had been applied to a particular field, then the automatically-passed parameter would be that field's value.

The float value returned by defineBoost becomes the weight of the class or field that was annotated. In this case, we increase a CustomerReview object's weight to 1.5 when it represents a five-star review. Otherwise, we keep the 1.0 default.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset