Search code examples
hibernatesortinghibernate-criteriahibernate-searchfull-text-indexing

Hibernate full text search custom order by


We want to add custom order by to hibernate full text search,suppose we want to search the record based on location, if the location is "country,state,city

Then we want to have the search with records in the top which are near to user

We followed following links.

using mysql "order by case" in hibernate criteria

But the order by clause is not getting added when we add it to criteria object

Sort is working only when we set to full Text Query object like below, here we can do only asc and desc, dynamic order by not.

Sort sort = new Sort( new SortField( "location", SortField.Type.STRING, false ) );
fullTextQuery.setSort( sort );

It is geo location based search.

we are storing the location value in mysql table column as "India,Karnataka,Bangalore" suppose user from Bangalore logins we need to show the records which are from Bangalore first at the top.

It would be helpful if we get some information regarding this, or any other way to achieve this problem.

Thanks, Mohsin


Solution

  • It sounds like you don't want to literally 'sort' those results but you want the results which match the location to be ranked very high, so to get them on top when performing a query sorted by score.

    Remember a full-text search by default will return results sorted by relevancy, so the matches which are most similar to the query will be returned first. The concept of "similarity" is something which you can control - and that's the point of using a more powerful full-text engine than a relational query.

    So you could get your results which have "location" matching "Bangalore" by adding a Boolean clause with the SHOULD operator, and giving this a strong boost in scoring.

    For example you could:

    Query combinedQuery = querybuilder
       .bool()
          .must( originalQuery )
          .should( querybuilder.keyword().onField("location").matching(place_keyword).createQuery(); )
    .createQuery();
    

    See these section of the documentation:

    You can verify how the boosting and weights are calculated by using projections with queries. You can have it produce the simple score, or even a full explanation on why that score got that value; for example:

    org.hibernate.search.FullTextQuery query =
       s.createFullTextQuery(luceneQuery, YourEntity.class);
    query.setProjection(
       FullTextQuery.SCORE,
       FullTextQuery.EXPLANATION,
       FullTextQuery.THIS);
    
    List results = query.list();
    Object[] firstResult = (Object[]) results.get(0);
    float score = firstResult[0];
    String explanation = firstResult[1];
    YourEntity o = (YourEntity) firstResult[2];
    

    Finally, you can also change the scoring formula to your liking, or read about the default Similarity implementation to help understand the scoring system and the "explanation" formula.