By default, search results come back in the order of their "relevance". In other words, they are ranked by the degree to which they match the query. We will discuss this further over the next two chapters, and learn how to adjust these relevance calculations.
However, we have the option to change the sorting to some other criteria altogether. In typical situations, you might sort by a date or numeric field, or by a string field in an alphabetical order. In all versions of the VAPORware Marketplace application going forward, users may now sort their search results by the app name.
To sort on a field, special consideration is required when that field is mapped for Lucene indexing. Normally when a string field is indexed, a default analyzer (explored in the next chapter) tokenizes the string. For example, if an App
entity's name
field is "Frustrated Flamingos", then separate entries are created in the Lucene index for "frustrated" and "flamingos". This allows for more powerful querying, but we want to sort based on the original untokenized value.
An easy way to support this is by mapping the field twice, which is perfectly fine! As we saw in Chapter 2, Mapping Entity Classes, Hibernate Search offers a plural @Fields
annotation. It wraps a comma-separated list of @Field
annotations, with different analyzer settings.
In the following code snippet, one @Field
is declared with the (tokenizing) defaults. The second one has its analyze
element sent to Analyze.NO
, to disable tokenization, and is given its own distinct field name in the Lucene index:
... @Column @Fields({ @Field, @Field(name="sorting_name", analyze=Analyze.NO) }) private String name; ...
This new field name can be used as follows to build a Lucene SortField
object, and attach it to a Hibernate Search FullTextQuery
object:
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
...
Sort sort = new Sort(
new SortField("sorting_name", SortField.STRING));
hibernateQuery.setSort(sort); // a FullTextQuery object
When a list of search results is later returned by hibernateQuery
, this list will be sorted by the app name, starting from A to Z.
Reverse sorting is possible as well. The SortField
class also offers a constructor with a third Boolean
parameter. If that parameter is set to true
, the sort will work in the exact opposite manner (for example, Z to A).