Search code examples
javaperformancehibernatehibernate-search

Hibernate Search performance suggestion about criteria


I am working with Hibernate Search for first time and I have some doubts. I appreciate if you can tell me some suggestions.

I have the following entity:

@Entity
public class User {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Long id;

 @Field(name = FIELD_LASTNAME, analyze = Analyze.YES, index = Index.YES)
 private String name;

 private int age;

.....

So, for search users which their age is 25 I do the following:

QueryBuilder qb = fullTextEntityManager.getSearchFactory()
    .buildQueryBuilder().forEntity(User.class).get();

Query luceneQuery = qb.keyword().onFields("name").matching("Geor").createQuery();

Query jpaQuery = fullTextEntityManager 
                .createFullTextQuery(luceneQuery, User.class)                             
                .setCriteriaQuery(fullTextEntityManager
                                  .createCriteria(User.class)
                                  .add(Restrictions.eq("user.age", 25)));

My Question are:

  1. Is It correct to use Criteria to filter information? / When is useful to use it?
  2. Should I index the property "age" using @Field?
  3. Should I index all entity's properties that I need to use to filter?
  4. How about performance, using indexed values or not?
  5. How to choose which values has to be indexed by lucene?

Thanks in advance


Solution

  • Is It correct to use Criteria to filter information? / When is useful to use it?

    No. Hibernate Search Lucene should not be mixed with Hibernate ORM Criteria queries. That is not supported. All you can set via the criteria API is the fetch mode for associations.

    Should I index the property "age" using @Field?

    Yes.

    Should I index all entity's properties that I need to use to filter?

    Absolutely. The most efficient way to search when using Hibernate Search is to make sure all information needed for the search is indexed and searchable via the Lucene index. You then use for example boolean queries to combine different search criteria. You also might want to think about how to index certain properties. For example, if you have numbers you can index them as numeric fields (see @NumericField). This will speed up range queries against these fields. In some cases you might even want to use a custom bridge. It all depends on your use-case and what you want to search for.

    How about performance, using indexed values or not?

    Provided you need full text search capabilities and you are going to use Hibernate Search, the best approach is to just use Hibernate Search queries.

    How to choose which values has to be indexed by lucene?

    You know your domain model best. You should know which fields you need to search on right now. These are the minimum fields you need to index now. If there are other fields you might need later, add them as well, unless you are really worried about index size. However, that is often not a problem. And even if you get it wrong and need to index fields later on, it is just a question of adding the required annotations and then rebuilding the index. For that particular purpose Search offers a very powerful mass indexer API.

    I hope this helps.