Question

My application, that uses Hibernate Search 4.5.0.Final, is working fine when I try to search with just one keyword. But if I try to use two keywords, the second keyword is not used by Hibernate Search, just the first one is considered by HS.

For example, if I try to search "James", the search works fine and the application returns all "James" that I have in the index. But if I try to search "James Hetfield", the results are, again, all "James" and not the unique result with name "James Hetfield". I need to treat "James Hetfield" as "James AND Hetfield".

EDIT: I've made a mistake. The search works with two keywords, but with "OR" and not "AND".

My code:

public List<Person> search(String keywords) throws DAOException {
    try {
        FullTextEntityManager fullTextEm = Search.getFullTextEntityManager(this.entityManager);
        QueryBuilder qb = fullTextEm.getSearchFactory().buildQueryBuilder().forEntity(Person.class).get();
        Query query = qb.keyword().onFields("name", "email", "username", "phone").matching(keywords).createQuery();
        FullTextQuery fullTextQuery = fullTextEm.createFullTextQuery(query);
        fullTextQuery.setProjection("name", "email", "username", "phone");
        Sort sortField = new Sort(new SortField("name_order", SortField.STRING));
        fullTextQuery.setSort(sortField);
        return fullTextQuery.getResultList();
    }
    catch (Exception e) {
        logger.error("Error searching index: " + keywords, e);
        throw new DAOException(e);
    }
}
Was it helpful?

Solution

Found a solution. I've split the String and used BooleanQuery. Thanks to @thomas. Here is my code:

Splitting:

String[] arrKeywords = keywords.split(" ");
this.search(Arrays.asList(arrKeywords));

And then, searching:

public List<Person> search(String keywordsList) throws DAOException {
    try {
        FullTextEntityManager fullTextEm = Search.getFullTextEntityManager(this.entityManager);
        QueryBuilder qb = fullTextEm.getSearchFactory().buildQueryBuilder().forEntity(Person.class).get();

        List<Query> queryList = new LinkedList<Query>();
        Query query = null;

        for (String keyword : keywordsList) {
            query = qb.keyword().onFields("name", "email", "username", "phone").matching(keyword).createQuery();
            queryList.add(query);
        }

        BooleanQuery finalQuery = new BooleanQuery();
        for (Query q : queryList) {
            finalQuery.add(q, Occur.MUST);
        }

        FullTextQuery fullTextQuery = fullTextEm.createFullTextQuery(query);
        fullTextQuery.setProjection("name", "email", "username", "phone");
        Sort sortField = new Sort(new SortField("name_order", SortField.STRING));
        fullTextQuery.setSort(sortField);
        return fullTextQuery.getResultList();
    }
    catch (Exception e) {
        logger.error("Error searching index: " + keywords, e);
        throw new DAOException(e);
    }
}

OTHER TIPS

Use the key word MUST during query building. Hibernate Search also supports combining queries using various strategies:

-SHOULD: the query should contain the matching elements of the subquery

-MUST: the query must contain the matching elements of the subquery

-MUST NOT: the query must not contain the matching elements of the subquery

The aggregations are similar to the boolean ones AND, OR and NOT.

    Query combinedQuery = queryBuilder
   .bool()

   .must(queryBuilder.phrase()
   .onField("productName).sentence("samsung galaxy s8")
   .createQuery())

   .must(queryBuilder.keyword()
   .onField("productCategory").matching("smartphone")
   .createQuery())

   .createQuery();


    // wrap Lucene query in an Hibernate Query object
    org.hibernate.search.jpa.FullTextQuery jpaQuery =
    fullTextEntityManager.createFullTextQuery(combinedQuery, Product.class);

    // execute search and return results (sorted by relevance as default)
    @SuppressWarnings("unchecked")
    List<Product> results = jpaQuery.getResultList();

This reference is obtained from the link http://www.baeldung.com/hibernate-search

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top