How do Hibernate Search sort the result of a search?

Asked

Viewed 792 times

2

I have a indexed search with the Hibernate Search but I can’t get Hibernate Search order the search result in the order of a given column, as for example the name column.

But there is a peculiarity. When the search is done using some term, the result is then ordered perfectly alphabetically. However, if I don’t put any term in the search (I want to return all results), then Hibernate Search no longer orders anything.

See the codes related to the two searches:

Using a filter (works)

Below is my method that searches filtering through a term. This search works perfectly and neatly by name (alphabetically).

public List<Colaborador> filtrar(String termo) throws DAOException {
    try {
        FullTextEntityManager fullTextEm = Search.getFullTextEntityManager(this.entityManager);
        QueryBuilder qb = fullTextEm.getSearchFactory().buildQueryBuilder().forEntity(Colaborador.class).get();
        Query query = qb.keyword().onFields("nome", "email", "usuario").matching(termo).createQuery();
        FullTextQuery fullTextQuery = fullTextEm.createFullTextQuery(query);

        // Ordenação ocorre corretamente aqui!
        Sort sortField = new Sort(new SortField("nome", SortField.STRING));

        fullTextQuery.setSort(sortField);
        return fullTextQuery.getResultList();
    }
    catch (Exception e) {
        logger.error("Erro ao filtrar colaboradores com termo: " + termo, e);
        throw new DAOException(e);
    }
}

Bringing all records (does not work ordering)

Below is a method very similar to what I posted above, however the method below just does not correctly sort the records that are returned by Hibernate Search. Note that it is the same entity (Colaborador.class) and yet the order by name doesn’t work properly.

public List<Colaborador> listarColaboradores() throws DAOException {
    FullTextEntityManager fullTextEm = Search.getFullTextEntityManager(this.entityManager);
    QueryBuilder qb = fullTextEm.getSearchFactory().buildQueryBuilder().forEntity(Colaborador.class).get();
    FullTextQuery fullTextQuery = fullTextEm.createFullTextQuery(qb.all().createQuery());

    // A mágica deveria ser feita aqui!
    Sort sortField = new Sort(new SortField("nome", SortField.STRING));

    fullTextQuery.setSort(sortField);
    return fullTextQuery.getResultList();
}

Has anyone been there? You know what might be happening?

1 answer

0


The problem was in my entity.

@Entity
@Indexed
@Table(name = "my_view")
public class Colaborador implements Serializable {

    private static final long serialVersionUID = 244555315052436669L;

    @Id
    @Field(store = Store.YES, index = Index.YES, analyze = Analyze.YES)
    @Column(name = "id", insertable = false, updatable = false)
    private Long id;

    @Field(store = Store.YES, index = Index.YES, analyze = Analyze.YES)
    @Column(name = "name", insertable = false, updatable = false)
    private String nome;

    @Field(store = Store.YES, index = Index.YES, analyze = Analyze.YES)
    @Column(name = "email", insertable = false, updatable = false)
    private String email;

    @Field(store = Store.YES, index = Index.YES, analyze = Analyze.YES)
    @Column(name = "user", insertable = false, updatable = false)
    private String usuario;

    //Getters e Setters omitidos
}

See that the attribute private String nome;, in which I wish to order my search, it is noted as follows:

@Field(store = Store.YES, index = Index.YES, analyze = Analyze.YES)
@Column(name = "nome", insertable = false, updatable = false)
private String nome;

Doing research and more research, I found a snippet in the Hibernate Search documentation which says the following:

Fields used for Sorting must not be analyzed.

So I changed the mapping of my entity to:

@Field(store = Store.YES, index = Index.YES, analyze = Analyze.NO)
@Column(name = "nome", insertable = false, updatable = false)
private String nome;

And I went to test my application. To my surprise the ordering worked, but the filter by name attribute, stopped working. I mean, I packed one thing and broke another. I went back to my research and ended up in the Hibernate Search documentation again.

I found that the same attribute can be mapped twice to Hibernate Search. So you can, in a mapping use the Analyze.YES and run the query on top of that mapping and a second mapping with Analyze.NO to sort. Sounds complicated? See code:

@Fields({
    @Field(name = "nome_ordem", store = Store.YES, index = Index.YES, analyze = Analyze.NO),
    @Field(name = "nome", store = Store.YES, index = Index.YES, analyze = Analyze.YES)
})
@Column(name = "nome", insertable = false, updatable = false)
private String nome;

Note that I create two indices for the same attribute. One is used as a filter field and the other as sorting. By doing so, I can then search for this attribute and also order it!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.