【问题标题】:hibernate search wildcard phrase queryhibernate搜索通配符短语查询
【发布时间】:2013-01-10 01:32:17
【问题描述】:

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

【问题讨论】:

    标签: hibernate lucene hibernate-search


    【解决方案1】:

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

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

    不过,更好的解决方案可能是依靠评分来为一组术语查询提供最佳匹配。如果您只是使用标准分析器将您指示的查询减少为一组三个术语:*irsTWiLdCaRdq*,而您指示的两个术语都会被找到,您想要的术语将首先返回,得分明显更高。您可以稍微磨练可接受的找到的文档,使用所需的术语进行搜索,例如:+title:*irsT +title:WiLdCaRd +title:q*。这将消除任何不包含所有三个术语的匹配项,尽管它们的顺序或其他术语的存在不会阻止匹配。

    另外,另一个注意事项:除非您将其设置为启用前导通配符,否则不允许像 *irst 这样的查询。如果可以避免,通常不鼓励这样做。使用前导通配符进行搜索可能会非常缓慢,除非您已针对它们优化索引(例如,请参阅 SOLR 的 ReversedWildcardFilterFactory)。

    【讨论】:

    • Lucene 实际上确实支持短语查询中的通配符,请参阅lucene.apache.org/core/4_0_0/core/org/apache/lucene/search/…。我不确定查询解析器是否可以构建这类查询。
    • @DanielNaber 是的,我以前遇到过。不过,这几乎不符合我的想法,因为它需要您手动枚举带有该前缀的所有术语,并且 MultiPhraseQuery 的 4.0.0 文档中列出的方法来实现这一点,IndexReader.terms(Term) 不再在 4.0.0 中存在或至少不再记录。我想说 Lucene 不支持短语查询中的通配符(您仍然不将通配符传递到查询中,而是自己定义通配符逻辑),但它们确实记录了您可能用来获得相同结果的 hack。
    猜你喜欢
    • 2014-06-07
    • 2013-08-07
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    相关资源
    最近更新 更多