如何配置lucene + hibernate并开发通配符查询,该查询与该字段值的任何确切部分匹配某些字段?例如,如果我们有一些字段“title”被索引,只有两个条目:“我的第一个通配符查询。”和“我的第二个通配符查询。”;然后,如果我们查询“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也不起作用(
答案 0 :(得分:4)
Lucene在短语查询中不支持通配符。有关如何在索引中表示数据的策略,可以让您完成它。
您将查询视为关键字,它会出现。在这种情况下,您应该在索引时将字段视为关键字,在这种情况下,您可以将整个标题作为单个术语进行搜索。带有空格的短语和关键词与Lucene完全不同,你不能互换使用它们。
但更好的解决方案可能是依靠评分来提供一组术语查询的最佳匹配。如果您只是使用标准分析器来缩小您指定的查询,则会指向三个术语:*irsT
WiLdCaRd
和q*
,同时找到您指定的两个术语,你想要的是先退回,得分高得多。您可以在某种程度上磨练可接受的已找到的文档,使用所需的术语进行搜索,例如:+title:*irsT +title:WiLdCaRd +title:q*
。这将消除任何不包含所有三个术语的匹配,但是它们的顺序或其他术语的存在不会阻止匹配。
此外,另一个注意事项:除非您将其设置为启用前导通配符,否则不允许*irst
之类的查询。如果你能避免这种情况,通常不鼓励这样做。使用前导通配符搜索可能会非常慢,除非您已为它们优化了索引(例如,参见SOLR的ReversedWildcardFilterFactory)。