hibernate搜索通配符短语查询

时间:2013-01-09 15:01:15

标签: hibernate lucene hibernate-search

如何配置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也不起作用(

1 个答案:

答案 0 :(得分:4)

Lucene在短语查询中不支持通配符。有关如何在索引中表示数据的策略,可以让您完成它。

您将查询视为关键字,它会出现。在这种情况下,您应该在索引时将字段视为关键字,在这种情况下,您可以将整个标题作为单个术语进行搜索。带有空格的短语和关键词与Lucene完全不同,你不能互换使用它们。

但更好的解决方案可能是依靠评分来提供一组术语查询的最佳匹配。如果您只是使用标准分析器来缩小您指定的查询,则会指向三个术语:*irsT WiLdCaRdq*,同时找到您指定的两个术语,你想要的是先退回,得分高得多。您可以在某种程度上磨练可接受的已找到的文档,使用所需的术语进行搜索,例如:+title:*irsT +title:WiLdCaRd +title:q*。这将消除任何不包含所有三个术语的匹配,但是它们的顺序或其他术语的存在不会阻止匹配。

此外,另一个注意事项:除非您将其设置为启用前导通配符,否则不允许*irst之类的查询。如果你能避免这种情况,通常不鼓励这样做。使用前导通配符搜索可能会非常慢,除非您已为它们优化了索引(例如,参见SOLR的ReversedWildcardFilterFactory)。