2013-01-09 88 views
1

如何配置lucene + hibernate並開發與該字段值的任何確切部分匹配某個字段的通配符查詢?例如,如果我們有一些字段「標題」被索引,並且只有兩個條目:「我的第一個通配符查詢」。和「我的第二個通配符查詢」。那麼如果我們查詢「irsT WiLdCaRd q」,那麼它只能返回第一個。也不一定要區分大小寫。冬眠搜索通配短語查詢

我已經試過這樣的事情:

FullTextSession ftSession = org.hibernate.search.Search.getFullTextSession((Session) em.getDelegate()); 
    QueryContextBuilder qbc = ftSession.getSearchFactory().buildQueryBuilder(); 
    EntityContext entityContext = qbc.forEntity(Book.class); 
    QueryBuilder qb = entityContext.get(); 
    org.apache.lucene.search.Query q = qb.keyword().wildcard().onField("title") 
      .ignoreAnalyzer().matching("*" + QueryParser.escape("irsT WiLdCaRd q").toLowerCase() + "*").createQuery(); 
    FullTextEntityManager ftEm = org.hibernate.search.jpa.Search.getFullTextEntityManager(em); 
    final FullTextQuery ftq = ftEm.createFullTextQuery(q, Book.class); 
    List list = ftq.getResultList(); 

和它不工作,因爲它是面向關鍵字和有通配符詞組沒有模擬。使用直接WildcardQuery也不起作用(

回答

4

Lucene的不支持通配符短語查詢。還有你如何表示索引數據的策略,可以讓你完成它。

你對待你的查詢作爲關鍵字出現,在這種情況下,您應該在索引時將該字段視爲關鍵字,在這種情況下,您可以搜索整個標題作爲單個詞語。對Lucene來說是非常不同的東西,你不能交替使用它們。

但是,更好的解決方案可能是依靠評分來提供一組術語queri上的最佳匹配ES。如果您只是使用標準分析器來減少您指定的一組三項條件:*irsTWiLdCaRdq*,而您找到的兩個術語都會找到,那麼您希望得到的那個將首先返回,並且得分會高得多。您可以在某種程度上磨練可接受的已發現文檔,並使用所需術語進行搜索,如:+title:*irsT +title:WiLdCaRd +title:q*。這將消除任何不包含所有三個詞的匹配,儘管它們的順序或其他詞的存在不會阻止匹配。

此外,另一個注意:像*irst這樣的查詢是不允許的,除非您將其設置爲啓用領先通配符。如果你能避免這種情況,這通常是不鼓勵的。預計搜索引導通配符會非常緩慢,除非您優化了索引(例如參見SOLR的ReversedWildcardFilterFactory)。

+1

Lucene實際上對短語查詢中的通配符有一些支持,請參閱https://lucene.apache.org/core/4_0_0/core/org/apache/lucene/search/MultiPhraseQuery.html。我不確定查詢解析器是否可以構建這些類型的查詢。 –

+1

@DanielNaber是的,我以前就遇到過這種情況。但是,這並不足以支持我的想法,因爲它需要您手動列舉所有帶有該前綴的術語,以及4.0.0文檔中「MultiPhraseQuery」中列出的方法來完成該操作,即IndexReader.terms(Term )'在4.0.0中不再存在,或至少不再有文檔記錄。我會說Lucene在短語查詢中不支持通配符(你仍然不會在查詢中傳遞通配符,而是自己定義通配符邏輯),但是它們確實記錄了可能用於獲得相同結果的黑客行爲。 – femtoRgon