1

lucene + hibernate を構成し、そのフィールド値の正確な部分でフィールドに一致するワイルドカード クエリを開発する方法は? たとえば、いくつかのフィールド「タイトル」がインデックス化されていて、そのエントリが「My first wildcard query」の 2 つだけであるとします。および「私の 2 番目のワイルドカード クエリ。」; 次に、「irsT WiLdCaRd q」を照会すると、最初の 1 つだけを返す必要があります。また、大文字と小文字を区別する必要はありません。

私はこのようなことを試しました:

    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

1 に答える 1

4

Lucene は、フレーズ クエリでのワイルドカードをサポートしていません。インデックス内のデータを表現する方法には、それを実現できる戦略があります。

クエリをキーワードとして扱っているようです。その場合、インデックス作成時にフィールドをキーワードとして扱う必要があります。その場合、タイトル全体を単一の用語として検索できます。スペースを含むフレーズとキーワードは、Lucene にとってはまったく異なるものであり、同じ意味で使用することはできません。

ただし、より良い解決策は、スコアリングに依存して、用語クエリのセットに最適な一致を提供することです。標準のアナライザーを使用して、指定したクエリを と の 3 つの用語のセットに減らす*irsT WiLdCaRdと、指定したq*両方の用語が検出されますが、必要な用語が最初に返され、スコアが大幅に高くなります。次のような必要な用語で検索して、許容可能な見つかったドキュメントをある程度絞り込むことができます +title:*irsT +title:WiLdCaRd +title:q*。これにより、3 つの用語すべてを含まない一致が除外されますが、それらの順序や他の用語の存在によって一致が妨げられることはありません。

また、別の注意:*irst先頭のワイルドカードを有効にするように設定しない限り、次のようなクエリは許可されません。回避できる場合、これは一般的に推奨されません。先頭のワイルドカードを使用した検索は、インデックスを最適化していない限り、非常に遅くなることが予想されます (たとえば、SOLR のReversedWildcardFilterFactoryを参照してください)。

于 2013-01-09T16:41:27.787 に答える