5.3. フィルタ


Apache Lucene には、カスタムフィルタリングプロセスに従ってクエリ結果をフィルタできる強力な機能があります。これは、特にフィルタをキャッシュおよび再利用できるため、追加データ制限を適用するのに非常に強力です。一部の使用例は以下のとおりです。
  • セキュリティ
  • 一時データ (先月のデータのみを表示するなど)
  • 生成フィルタ (該当するカテゴリに制限される検索など)
  • その他
Hibernate Search は透過的にキャッシュされるパラメータ設定可能な名前付きフィルタの概念を導入することにより、このコンセプトを押し進めています。Hibernate Core フィルタの概念を知っているユーザーにとってこの API は非常に似ています。

例5.14 該当するクエリに対して完全テキストフィルタを有効化

fullTextQuery = s.createFullTextQuery( query, Driver.class );
fullTextQuery.enableFullTextFilter("bestDriver");
fullTextQuery.enableFullTextFilter("security").setParameter( "login", "andre" );
fullTextQuery.list(); //returns only best drivers where andre has credentials
Copy to Clipboard Toggle word wrap
この例では、クエリの上部に 2 つのフィルタが有効化されています。任意の数のフィルタを有効化 (または無効化) できます。
フィルタの宣言は @FullTextFilterDef アノテーションを使用して行われます。このアノテーションはフィルタが後で適用されるクエリに関係なく任意の @Indexed エンティティに対するものです。これは、フィルタ定義がグローバルであり、名前が一意である必要があることを暗黙的に示しています。SearchException は同じ名前を持つ 2 つの異なる @FullTextFilterDef アノテーションが定義された場合にスローされます。各名前付きフィルタは実際のフィルタ実装を指定する必要があります。

例5.15 フィルタの定義と実装

@Entity
@Indexed
@FullTextFilterDefs( {
    @FullTextFilterDef(name = "bestDriver", impl = BestDriversFilter.class), 
    @FullTextFilterDef(name = "security", impl = SecurityFilterFactory.class) 
})
public class Driver { ... }
Copy to Clipboard Toggle word wrap
public class BestDriversFilter extends org.apache.lucene.search.Filter {

    public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
        OpenBitSet bitSet = new OpenBitSet( reader.maxDoc() );
        TermDocs termDocs = reader.termDocs( new Term( "score", "5" ) );
        while ( termDocs.next() ) {
            bitSet.set( termDocs.doc() );
        }
        return bitSet;
    }
}
Copy to Clipboard Toggle word wrap
BestDriversFilter は、スコアが 5 のドライバに結果セットを削減する単純な Lucene フィルタの例です。この例では、指定されたフィルタが org.apache.lucene.search.Filter を直接実装し、引数を持たないコンストラクタを含みます。
フィルタ作成で追加のステップが必要な場合、または使用するフィルタが引数を持たないコンストラクタを含まない場合は、以下のファクトリパターンを使用できます。

例5.16 ファクトリパターンを使用したフィルタの作成

@Entity
@Indexed
@FullTextFilterDef(name = "bestDriver", impl = BestDriversFilterFactory.class)
public class Driver { ... }

public class BestDriversFilterFactory {

    @Factory
    public Filter getFilter() {
        //some additional steps to cache the filter results per IndexReader
        Filter bestDriversFilter = new BestDriversFilter();
        return new CachingWrapperFilter(bestDriversFilter);
    }
}
Copy to Clipboard Toggle word wrap
Hibernate Search は @Factory によりアノテートされたメソッドを探し、それを使用してフィルタインスタンスを構築します。ファクトリは引数を持たないコンストラクタを持つ必要があります。JBoss Seam に精通しているユーザーにとって、これはコンポーネントファクトリパターンに似ていますが、アノテーションは異なります。
名前付きフィルタはパラメータをフィルタに渡す必要がある場合に役に立ちます。たとえば、セキュリティフィルタは適用するセキュリティレベルを知りたいことがあります。

例5.17 定義されたフィルタへのパラメータの引き渡し

fullTextQuery = s.createFullTextQuery( query, Driver.class );
fullTextQuery.enableFullTextFilter("security").setParameter( "level", 5 );
Copy to Clipboard Toggle word wrap
各パラメータ名は、対象の名前付きフィルタ定義のフィルタまたはフィルタファクトリに対して関連付けられた設定メソッドを持つ必要があります。

例5.18 実際のフィルタ実装でのパラメータの使用

public class SecurityFilterFactory {
    private Integer level;

    /**
     * injected parameter
     */
    public void setLevel(Integer level) {
        this.level = level;
    }

    @Key public FilterKey getKey() {
        StandardFilterKey key = new StandardFilterKey();
        key.addParameter( level );
        return key;
    }

    @Factory
    public Filter getFilter() {
        Query query = new TermQuery( new Term("level", level.toString() ) );
        return new CachingWrapperFilter( new QueryWrapperFilter(query) );
    }
}
Copy to Clipboard Toggle word wrap
メソッドが @Key をアノテートし、FilterKey オブジェクトを返すことに注意してください。返されたオブジェクトは特別なコントラクトを持ちます。キーオブジェクトは、該当する Filter タイプが同じであり、パラメータのセットが同じである場合にのみ 2 つのキーが同じになるよう equals() / hashcode() を実装する必要があります。つまり、2 つのフィルタキーは、キーが生成されるフィルタを交換できる場合にのみ同じになります。キーオブジェクトはキャッシュメカニズムでキーとして使用されます。
@Key メソッドは以下の場合にのみ必要です。
  • フィルタキャッシュシステムを有効にした場合 (デフォルトで有効)
  • フィルタがパラメータを持っている場合
ほとんどの場合、StandardFilterKey 実装を使用するだけで十分です。これにより、equals() / hashcode() 実装が同じ各パラメータとハードコードメソッドに委譲されます。
以前に述べたように、定義されたフィルタはデフォルトでキャッシュされ、キャッシュは、必要な場合にメモリを廃棄できるようハード参照とソフト参照の組み合わせを使用します。ハード参照キャッシュは最後に使用されたフィルタを追跡し、必要な場合に使用頻度が最も低いフィルタを SoftReferences に変換します。ハード参照キャッシュの制限に達したら、追加のフィルタは SoftReferences としてキャッシュされます。ハード参照キャッシュのサイズを調整するために、hibernate.search.filter.cache_strategy.size (デフォルトで 128) を使用します。フィルタキャッシュの上級ユーザーの場合は、独自の FilterCachingStrategy を実装できます。クラス名は hibernate.search.filter.cache_strategy により定義されます。
このフィルタキャッシュメカニズムを実際のフィルタ結果のキャッシュと混同しないでください。Lucene では、CachingWrapperFilter の周りで IndexReader を使用してフィルタをラップすることは一般的です。コストが高井再計算を回避するために、ラッパーは getDocIdSet(IndexReader reader) メソッドから返された DocIdSet をキャッシュします。計算された DocIdSet は同じ IndexReader インスタンスに対してのみキャッシュ可能であることに注意してください (リーダーはインスタンスが開かれたときのインデックスの状態を表すため)。ドキュメントリストは開かれた IndexReader 内で変更できません。ただし、キャッシュされた DocIdSet を再計算する必要があるため、異なる/新しい IndexReader インスタンスは、Document の異なるセット上で動作します (異なるインデックスから、または単にインデックスが変更されたため)。
また、Hibernate Search はキャッシュのこの側面でも役に立ちます。デフォルトでは、@FullTextFilterDef cache フラグは FilterCacheModeType.INSTANCE_AND_DOCIDSETRESULTS に設定されます。この結果、フィルタインスタンスが自動的にキャッシュされ、CachingWrapperFilter の Hibernate 固有の実装の周りに指定されたフィルタがラップされます (org.hibernate.search.filter.CachingWrapperFilter)。このクラス SoftReference の Lucene のバージョンは、ハード参照数とともに使用されます (フィルタキャッシュの説明を参照)。ハード参照数は hibernate.search.filter.cache_docidresults.size (デフォルト値は 5) を使用して調整できます。ラップの動作は @FullTextFilterDef.cache パラメータを使用して制御できます。このパラメータには 3 つの異なる値が存在します。
Expand
定義
FilterCacheModeType.NONE Hibernate Search によりフィルタインスタンスと結果がキャッシュされません。各フィルタコールごとに、新しいフィルタインスタンスが作成されます。この設定はすぐに変わるデータセットやメモリの制約が強い環境に役に立つことがあります。
FilterCacheModeType.INSTANCE_ONLY フィルタインスタンスはキャッシュされ、同時 Filter.getDocIdSet() コールで再利用されます。DocIdSet の結果はキャッシュされません。この設定は、フィルタが独自のキャッシュメカニズムを使用したり、フィルタの結果がアプリケーション固有のイベントのため動的に変化したりする場合 (両方の場合に DocIdSet キャッシュは不必要になります) に役に立ちます。
FilterCacheModeType.INSTANCE_AND_DOCIDSETRESULTS フィルタインスタンスと DocIdSet 結果の両方はキャッシュされます。これはデフォルト値です。
なぜフィルタをキャッシュする必要があるのでしょうか? フィルタキャッシュが有用な場合は以下の 2 つです。
  • システムが対象のエンティティインデックスを頻繁に更新しない (つまり、IndexReader が頻繁に再利用される)
  • フィルタの DocIdSet を計算するのにコストがかかる (クエリを実行するのにかかる時間と比較)
トップに戻る
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。 最新の更新を見る.

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

Theme

© 2025 Red Hat