2014-03-28 155 views
1

我的應用程序使用Hibernate搜索4.5.0.Final,當我嘗試使用一個關鍵字進行搜索時工作正常。但是如果我嘗試使用兩個關鍵字,第二個關鍵字不會被Hibernate Search使用,只有第一個關鍵字被HS考慮。在Hibernate搜索中使用多個關鍵字進行索引搜索

例如,如果我嘗試搜索「詹姆斯」,搜索工作正常,應用程序將返回所有「詹姆斯」我有在索引中。但是如果我試圖搜索「詹姆斯·赫特菲爾德」,結果又是所有「詹姆斯」,而不是名字爲「詹姆斯·赫特菲爾德」的獨特結果。我需要把「詹姆斯·赫特菲爾德」爲「詹姆斯赫特菲爾德」

編輯:我犯了一個錯誤。有兩個關鍵字,但是,用「OR」,而不是「與」搜索工作。

我的代碼:

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); 
    } 
} 
+0

獲得?你可以嘗試在匹配()之前調用'ignoreAnalyzer()'嗎? – Thomas

+0

另一種選擇可能是拆分字符串,併發出使用'BooleanJunction'和調用'junction.must(子查詢)'每個單詞的查詢。 – Thomas

+0

我想我沒有使用任何分析儀,因爲我沒有指定任何分析儀。也許我正在使用默認(如果有)。我試圖調用'.ignoreAnalyzer()',現在它找不到任何東西,即使只有一個關鍵字。 –

回答

4

實測值的溶液中。我已經分割了字符串並使用了BooleanQuery。感謝@thomas。這裏是我的代碼:

分裂:

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

,然後搜索:

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); 
    } 
} 
0

構建查詢時使用的關鍵詞必須的。

-SHOULD:Hibernate Search的使用也不同戰略支持組合查詢的查詢應該包含的子查詢匹配元素

- 必須:查詢必須包含子查詢

- 必須的匹配元素NOT:查詢不能包含子查詢

的聚合類似於布爾類型的AND,OR和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(); 

此引用從您正在使用哪種分析儀的鏈接http://www.baeldung.com/hibernate-search