検索

14.3. クエリ

download PDF
Hibernate Search は Lucene クエリーを実行し、Hibernate セッションによって管理されるドメインオブジェクトを取得できます。この検索は、Hibernate パラダイムを離れることなく Lucene の機能を提供し、HQL、基準クエリー、ネイティブ SQL クエリーなど、Hibernate の従来の検索メカニズムに別の特性を与えます。
クエリーの準備と実行は、以下の 4 つの手順で構成されます。
  • FullTextSession の作成
  • Hibernate Search クエリー DSL (推奨) または Lucene Query API を使用した Lucene クエリーの作成
  • org.hibernate.Query を使用した Lucene クエリーのラップ
  • たとえば、を呼び出して検索を実行しますlist()また scroll()
クエリー機能にアクセスするには、FullTextSession を使用します。この検索固有のセッションは、クエリーおよびインデックス機能を提供するために通常の org.hibernate.Session をラップします。

例14.30 FullTextSession の作成

Session session = sessionFactory.openSession();
...
FullTextSession fullTextSession = Search.getFullTextSession(session);
FullTextSession を使用して、Hibernate Search クエリー DSL またはネイティブの Lucene クエリーのいずれかでフルテキストクエリーを構築します。
Hibernate Search クエリー DSL を使用する場合は、以下のコードを使用します。
final QueryBuilder b = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity( Myth.class ).get();

org.apache.lucene.search.Query luceneQuery =
    b.keyword()
        .onField("history").boostedTo(3)
        .matching("storm")
        .createQuery();

org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery );
List result = fullTextQuery.list(); //return a list of managed objects
または、Lucene クエリーパーサーまたは Lucene プログラム API を使用して Lucene クエリーを書き込みます。

例14.31 QueryParser を介した Lucene クエリーの作成

SearchFactory searchFactory = fullTextSession.getSearchFactory();
org.apache.lucene.queryParser.QueryParser parser = 
    new QueryParser("title", searchFactory.getAnalyzer(Myth.class) );
try {
    org.apache.lucene.search.Query luceneQuery = parser.parse( "history:storm^3" );
}
catch (ParseException e) {
    //handle parsing failure
}

org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery);
List result = fullTextQuery.list(); //return a list of managed objects
Lucene クエリーに構築された Hibernate クエリーは org.hibernate.Query です。このクエリーは、HQL (Hibernate Query Language)、Native、および Criteria などの他の Hibernate クエリー機能と同じパラダイムに残ります。クエリーには、list()uniqueResult()iterate()scroll() などのメソッドを使用します。
Hibernate Java Persistence API では、同じ拡張機能を利用できます。

例14.32 JPAAPI を使用した検索クエリーの作成

EntityManager em = entityManagerFactory.createEntityManager();

FullTextEntityManager fullTextEntityManager = 
    org.hibernate.search.jpa.Search.getFullTextEntityManager(em);

...
final QueryBuilder b = fullTextEntityManager.getSearchFactory()
    .buildQueryBuilder().forEntity( Myth.class ).get();

org.apache.lucene.search.Query luceneQuery =
    b.keyword()
        .onField("history").boostedTo(3)
        .matching("storm")
        .createQuery();
javax.persistence.Query fullTextQuery = fullTextEntityManager.createFullTextQuery( luceneQuery );

List result = fullTextQuery.getResultList(); //return a list of managed objects
注記
これらの例では、Hibernate API が使われています。FullTextQuery の取得方法を調整すると、同じ例を Java Persistence API で記述することもできます。

14.3.1. クエリーの構築

Hibernate Search クエリーは Lucene クエリーにビルドされるため、ユーザーはすべての Lucene クエリータイプを使用できます。クエリーを構築すると、Hibernate Search はクエリー操作 API として org.hibernate.Query を使用して追加のクエリー処理を行います。

14.3.1.1. Lucene API を使用した Lucene クエリーの構築

Lucene API では、クエリーパーサー(簡単なクエリー) または Lucene プログラム API (複雑なクエリー) のいずれかを使用します。Lucene クエリーの構築は、Hibernate Search ドキュメントの範囲外です。詳細は、オンラインの Lucene ドキュメント、または『Lucene in Action』 または 『Hibernate Search in Action』 を参照してください。

14.3.1.2. Lucene クエリーの構築

Lucene プログラム API は、フルテキストクエリーを有効にします。ただし、Lucene プログラム API を使用する場合は、パラメーターを同等の文字列に変換する必要があります。また、正しいアナライザーを正しいフィールドに適用する必要もあります。たとえば、ngram アナライザーは、特定の単語に対するトークンとして複数の ngrams を使用するため、そのように検索する必要があります。このタスクには QueryBuilder を使用することが推奨されます。
Hibernate Search のクエリー API は変動しており、以下の主要な特徴があります。
  • メソッド名は英語です。そのため、API 操作は、一連の英語のフレーズおよび命令として読み取り、理解することができます。
  • IDE オートコンプリートを使用します。これは、現在の入力プレフィックスの完了を容易にし、ユーザーが適切なオプションを選択できるようにします。
  • 多くの場合、チェーンメソッドパターンを使用します。
  • API 操作を簡単に使用でき、読み取ることができます。
API を使用するには、まず、指定の indexedentitytype に割り当てられるクエリービルダーを作成します。この QueryBuilder は、使用するアナライザーと、適用するフィールドブリッジを認識します。複数の QueryBuilder (クエリーのルートに関連するエンティティータイプごとに 1 つ) を作成できます。QueryBuilderSearchFactory から派生します。
QueryBuilder mythQB = searchFactory.buildQueryBuilder().forEntity( Myth.class ).get();
特定のフィールドに使用されるアナライザーも上書きできます。
QueryBuilder mythQB = searchFactory.buildQueryBuilder()
    .forEntity( Myth.class )
        .overridesForField("history","stem_analyzer_definition")
    .get();
クエリービルダーを使用して Lucene クエリーをビルドできるようになりました。Lucene プログラム API を使用してアセンブルされた Lucene のクエリーパーサーまたは Query オブジェクトを使用して生成されたカスタマイズされたクエリーは、Hibernate Search DSL とともに使用されます。

14.3.1.3. キーワードのクエリー

以下の例は、特定の単語を検索する方法を示しています。
Query luceneQuery = mythQB.keyword().onField("history").matching("storm").createQuery();
表14.4 キーワードクエリーパラメーター
パラメーター 説明
keyword() 特定の単語を検索するには、このパラメーターを使用します。
onField() このパラメーターを使用して、単語を検索する lucene フィールドを指定します。
matching() このパラメーターを使用して、検索文字列の一致を指定します。
createQuery() Lucene クエリーオブジェクトを作成します。
  • 「storm」という値が history FieldBridge から渡されます。これは、数値または日付が必要な場合に便利です。
  • フィールドブリッジの値は、history フィールドインデックス化に使用されるアナライザーに渡されます。これにより、クエリーはインデックス (小文字、ngram、スチミングなど) よりも、同じ用語変換を使用します。分析プロセスで指定の単語が複数生成されると、ブールクエリーが SHOULD 論理 (おおよそ OR 論理) とともに使用されます。
タイプ文字列ではないプロパティーを検索します。
@Indexed 
public class Myth {
  @Field(analyze = Analyze.NO) 
  @DateBridge(resolution = Resolution.YEAR)
  public Date getCreationDate() { return creationDate; }
  public Date setCreationDate(Date creationDate) { this.creationDate = creationDate; }
  private Date creationDate;
  
  ...
}

Date birthdate = ...;
Query luceneQuery = mythQb.keyword().onField("creationDate").matching(birthdate).createQuery();
注記
プレーンな Lucene では、Date オブジェクトをその文字列表現 (この場合は年) に変換する必要がありました
この変換は、FieldBridgeobjectToString メソッド (およびすべての組み込み FieldBridge 実装) がある場合、すべてのオブジェクトに対して機能します。
以下の例では、ngram アナライザーを使用するフィールドを検索します。ngram アナライザーは単語の ngrams インデックスを連続させるため、ユーザーの誤字を防ぎます。たとえば、hibernate という単語の 3 グラムは hib、ibe、ber、ern、rna、nat、ate です。
@AnalyzerDef(name = "ngram",
  tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class ),
  filters = {
    @TokenFilterDef(factory = StandardFilterFactory.class),
    @TokenFilterDef(factory = LowerCaseFilterFactory.class),
    @TokenFilterDef(factory = StopFilterFactory.class),
    @TokenFilterDef(factory = NGramFilterFactory.class,
      params = { 
        @Parameter(name = "minGramSize", value = "3"),
        @Parameter(name = "maxGramSize", value = "3") } )
  }
)

public class Myth {
  @Field(analyzer=@Analyzer(definition="ngram") 
  public String getName() { return name; }
  public String setName(String name) { this.name = name; }
  private String name;
  
  ...
}

Date birthdate = ...;
Query luceneQuery = mythQb.keyword().onField("name").matching("Sisiphus")
   .createQuery();
一致する単語「Sisiphus」は小文字になり、3 つのグラム (sis、isi、sip、iph、phu、hus) に分けられます。これらの各 ngram はクエリーの一部になります。ユーザーは、Sysiphus myth ( y) を見つけることができます。ユーザーに透過的に実行されます。
注記
ユーザーが特定のフィールドでフィールドブリッジまたはアナライザーを使用したくない場合は、ignoreAnalyzer()またignoreFieldBridge()関数を呼び出すことができます。
同一フィールドで複数の使用可能な単語を検索するには、それらすべてを一致するシーケンスに追加します。
//search document with storm or lightning in their history
Query luceneQuery = 
    mythQB.keyword().onField("history").matching("storm lightning").createQuery();
複数のフィールドで同じ単語を検索するには、onFields方法。
Query luceneQuery = mythQB
    .keyword()
    .onFields("history","description","name")
    .matching("storm")
    .createQuery();
場合によっては、同じ用語を検索する場合でも、あるフィールドを別のフィールドとは異なる方法で処理する必要があります。その場合は、andField() メソッドを使用します。
Query luceneQuery = mythQB.keyword()
    .onField("history")
    .andField("name")
      .boostedTo(5)
    .andField("description")
    .matching("storm")
    .createQuery();
上記の例では、フィールド名のみが 5 に改善されています。

14.3.1.4. Fuzzy クエリー

Levenshtein 距離アルゴリズムに基づく fuzzy クエリーを実行するには、keyword クエリーから始め、fuzzy フラグを追加します。
Query luceneQuery = mythQB
    .keyword()
      .fuzzy()
        .withThreshold( .8f )
        .withPrefixLength( 1 )
    .onField("history")
    .matching("starm")
    .createQuery();
threshold は、両方の用語で照合が考慮される制限です。0 から 1 までの小数で、デフォルト値は 0.5 です。prefixLength は、「fuzzyness」で無視される接頭辞の長さです。デフォルト値は 0 ですが、多数の異なる用語を含むインデックスにはゼロ以外の値が推奨されます。

14.3.1.5. ワイルドカードクエリー

ワイルドカードクエリーは、単語の一部のみが認識される状況で役に立ちます。? は単一文字で、* は複数文字を表します。パフォーマンス維持のために、クエリーは ? または * で開始しないことが推奨されます。
Query luceneQuery = mythQB
    .keyword()
      .wildcard()
    .onField("history")
    .matching("sto*")
    .createQuery();
注記
ワイルドカードクエリーは、一致する用語にアナライザーを適用しません。経験のある * または ? のリスクが高すぎます。

14.3.1.6. フレーズクエリー

これまで、単語または単語セットを見てきましたが、ユーザーは正確な単語または概算した単語を検索することもできます。使用するphrase()そうするために。
Query luceneQuery = mythQB
    .phrase()
    .onField("history")
    .sentence("Thou shalt not kill")
    .createQuery();
おおよその文は、slop 係数を追加することで検索できます。slop 係数は、文内で許可される他の単語の数を表します。これは、within または near 演算子のように機能します。
Query luceneQuery = mythQB
    .phrase()
      .withSlop(3)
    .onField("history")
    .sentence("Thou kill")
    .createQuery();

14.3.1.7. 範囲クエリー

範囲クエリーは、指定された範囲内 (含まれるかどうか) または特定の範囲 (含まれるかどうか) を下回る、もしくは上回る値を検索します。
//look for 0 <= starred < 3
Query luceneQuery = mythQB
    .range()
    .onField("starred")
    .from(0).to(3).excludeLimit()
    .createQuery();

//look for myths strictly BC
Date beforeChrist = ...;
Query luceneQuery = mythQB
    .range()
    .onField("creationDate")
    .below(beforeChrist).excludeLimit()
    .createQuery();

14.3.1.8. クエリーの統合

クエリーを集約 (結合) して、より複雑なクエリーを作成できます。以下の集計演算子を使用できます。
  • SHOULD: クエリーには、サブクエリーの一致する要素が含まれる必要があります。
  • MUST: クエリーには、サブクエリーの一致する要素が含まれる必要があります。
  • MUST NOT: クエリーには、サブクエリーの一致する要素を含めないでください。
サブクエリーは、ブール値クエリー自体を含む任意の Lucene クエリーにすることができます。

例14.33 クエリー してはいけません

//look for popular modern myths that are not urban
Date twentiethCentury = ...;
Query luceneQuery = mythQB
    .bool()
      .must( mythQB.keyword().onField("description").matching("urban").createQuery() )
        .not()
      .must( mythQB.range().onField("starred").above(4).createQuery() )
      .must( mythQB
        .range()
        .onField("creationDate")
        .above(twentiethCentury)
        .createQuery() )
    .createQuery();

例14.34 クエリー する必要があります

//look for popular myths that are preferably urban
Query luceneQuery = mythQB
    .bool()
      .should( mythQB.keyword().onField("description").matching("urban").createQuery() )
      .must( mythQB.range().onField("starred").above(4).createQuery() )
    .createQuery();

例14.35 クエリーし ない

//look for all myths except religious ones
Query luceneQuery = mythQB
    .all()
      .except( monthQb
        .keyword()
        .onField( "description_stem" )
        .matching( "religion" )
        .createQuery() 
      )
    .createQuery();

14.3.1.9. クエリーオプション

Hibernate Search クエリー DSL は使いやすく、読みやすいクエリー API です。Lucene クエリーを受け入れて生成すると、DSL で対応していないクエリータイプを組み込むことができます。
以下は、クエリータイプおよびフィールドのクエリーオプションの要約です。
  • boostedTo (クエリータイプおよびフィールド上) は、クエリー全体または特定のフィールドを指定された係数に改善します。
  • withConstantScore (クエリーで) は、ブーストに等しい一定のスコアを持つクエリーに一致するすべての結果を返します。
  • filteredBy(Filter)(クエリー時) Filter インスタンスを使用してクエリー結果をフィルタリングします。
  • ignoreAnalyzer (フィールド上) このフィールドを処理するとき、アナライザーを無視します。
  • ignoreFieldBridge (フィールド上) このフィールドを処理するときにフィールドブリッジを無視します。

例14.36 クエリーオプションの組み合わせ

Query luceneQuery = mythQB
    .bool()
      .should( mythQB.keyword().onField("description").matching("urban").createQuery() )
      .should( mythQB
        .keyword()
        .onField("name")
          .boostedTo(3)
          .ignoreAnalyzer()
        .matching("urban").createQuery() )
      .must( mythQB
        .range()
          .boostedTo(5).withConstantScore()
        .onField("starred").above(4).createQuery() )
    .createQuery();

14.3.1.10. Hibernate Search クエリーの構築

14.3.1.10.1. 一般性
Lucene クエリーの構築後に、Hibernate クエリー内にラップします。クエリーはインデックス化されたすべてのエンティティーを検索し、明示的に設定しない限り、インデックス化されたクラスのすべてのタイプを返します。

例14.37 Lucene クエリーを Hibernate クエリーでラップする

FullTextSession fullTextSession = Search.getFullTextSession( session );
org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery );
パフォーマンスを改善するために、返されたタイプを以下のように制限します。

例14.38 エンティティータイプによる検索結果のフィルタリング

fullTextQuery = fullTextSession
    .createFullTextQuery( luceneQuery, Customer.class );

// or

fullTextQuery = fullTextSession
    .createFullTextQuery( luceneQuery, Item.class, Actor.class );
次の例の最初の部分は、一致する Customer のみを返します。同じ例の次の部分は、一致する ActorItem を返します。タイプ制限はポリモーフィックです。そのため、2 つのサブクラス Salesman と、ベースクラス PersonCustomer は、結果タイプに基づいてフィルタリングする Person.class を指定します。
14.3.1.10.2. ページネーション
パフォーマンスの低下を回避するには、クエリーごとに返されたオブジェクトの数を制限することが推奨されます。あるページから別のページに移動するユーザーは、非常に一般的なユースケースです。ページネーションを定義する方法は、プレーンの HQL または基準クエリーでのページネーションの定義と似ています。

例14.39 検索クエリーのページ付けを定義する

org.hibernate.Query fullTextQuery = 
    fullTextSession.createFullTextQuery( luceneQuery, Customer.class );
fullTextQuery.setFirstResult(15); //start from the 15th element
fullTextQuery.setMaxResults(10); //return 10 elements
注記
を介してページネーションに関係なく、一致する要素の総数を取得することは引き続き可能です。 fulltextQuery.getResultSize()
14.3.1.10.3. ソート
Apache Lucene には、柔軟で強力な結果ソートメカニズムが含まれています。デフォルトの並び替えは関連により行われ、さまざまなユースケースに適しています。Lucene Sort オブジェクトを使用し、他のプロパティーでソートするようにソートメカニズムを変更できます。

例14.40 Lucene ソート の指定

org.hibernate.search.FullTextQuery query = s.createFullTextQuery( query, Book.class );
org.apache.lucene.search.Sort sort = new Sort(
    new SortField("title", SortField.STRING));
query.setSort(sort);
List results = query.list();
注記
ソートに使用されるフィールドは、トークン化できません。トークン化についての詳細は、「@Field」 を参照してください 。
14.3.1.10.4. ストラテジーの取得
Hibernate Search は、戻り値の型が単一のクラスに制限されている場合に、単一のクエリーを使用してオブジェクトをロードします。Hibernate Search は、ドメインモデルで定義された静的なフェッチストラテジーによって制限されます。以下のように、特定のユースケースのフェッチストラテジーを微調整すると便利です。

例14.41 クエリーでの FetchMode の指定

Criteria criteria = 
    s.createCriteria( Book.class ).setFetchMode( "authors", FetchMode.JOIN );
s.createFullTextQuery( luceneQuery ).setCriteriaQuery( criteria );
この例では、クエリーは LuceneQuery に一致するすべての Books を返します。Authors コレクションは、SQL の外部結合を使用して同じクエリーからロードされます。
条件クエリー定義では、タイプは提供された基準クエリーに基づいて推測されます。そのため、返されたエンティティータイプを制限する必要はありません。
重要
フェッチモードは、唯一の調整可能なプロパティーです。getResultSize() は制限のある Criteria とともに使用された場合に SearchException をスローするため、Criteria クエリーで制限 (完全な句) を使用しないでください。
複数のエンティティーが予想される場合は、使用しないでくださいsetCriteriaQuery
14.3.1.10.5. プロジェクション
場合によっては、プロパティーの小さなサブセットのみが必要となります。Hibernate Search を使用して、以下のようにプロパティーのサブセットを取得します。
Hibernate Search は Lucene インデックスからプロパティーを抽出し、それらをオブジェクト表現に変換し、Object[] のリストを返します。プロジェクションは、データベースのラウンドトリップが長くなるのを防ぎます。ただし、以下の制限があります。
  • 予測されるプロパティーはインデックス (@Field(store=Store.YES)) に保存され、インデックスサイズが増えます。
  • 予測されるプロパティーは、org.hibernate.search.bridge.TwoWayFieldBridge または org.hibernate.search.bridge.TwoWayStringBridge を実装する FieldBridge を使用する必要があり、後者はより単純なバージョンになります。
    注記
    Hibernate Search の組み込みタイプはすべて双方向です。
  • インデックス化されたエンティティーまたはその埋め込み関連の簡単なプロパティーのみを展開できます。したがって、埋め込みエンティティー全体を展開できません。
  • @IndexedEmbedded でインデックス化されるコレクションやマップで機能しません。
Lucene は、クエリー結果に関するメタデータ情報を提供します。インジェクト定数を使用してメタデータを取得します。

例14.42 投影法を使用したメタデータの取得

org.hibernate.search.FullTextQuery query = 
    s.createFullTextQuery( luceneQuery, Book.class );
query.setProjection( FullTextQuery.SCORE, FullTextQuery.THIS, "mainAuthor.name" );
List results = query.list();
Object[] firstResult = (Object[]) results.get(0);
float score = firstResult[0];
Book book = firstResult[1];
String authorName = firstResult[2];
フィールドは、以下のプロジェクションと組み合わせることができます。
  • FullTextQuery.THIS 初期化され管理されたエンティティーを返します (展開されていないクエリーが実行される場合)。
  • FullTextQuery.DOCUMENT 展開されるオブジェクトに関連する Lucene ドキュメントを返します。
  • FullTextQuery.OBJECT_CLASS: インデックス化されたエンティティーのクラスを返します。
  • FullTextQuery.SCORE: クエリーのドキュメントスコアを返します。スコアは、あるクエリーの結果を別のクエリーに対する比較には便利ですが、異なるクエリーの結果を比較する場合に有用ではありません。
  • FullTextQuery.ID: 予測されるオブジェクトの ID プロパティー値。
  • FullTextQuery.DOCUMENT_ID: Lucene ドキュメント ID。この値を Lucene ドキュメント ID として使用すると、異なる 2 つの IndexReader を開くたびに変更される可能性があります。
  • FullTextQuery.EXPLANATION: 指定のクエリーの一致するオブジェクト/ドキュメントの Lucene Explanation オブジェクトを返します。これは、大量のデータを取得するのには適していません。通常、実行の説明は、一致する要素ごとに Lucene クエリー全体を実行することを意味します。そのため、展開が推奨されます。
14.3.1.10.6. オブジェクト初期化ストラテジーのカスタマイズ
デフォルトでは、Hibernate Search は最適なストラテジーを使用して、完全なテキストクエリーに一致するエンティティーを初期化します。1 つ (または複数) のクエリーを実行して、必要なエンティティーを取得します。このアプローチでは、取得したエンティティーが永続コンテキスト (セッション) または 2 次レベルキャッシュにほとんど存在しないデータベースのストライプが最小限に抑えられます。
2 次キャッシュにエンティティーが存在する場合は、データベースオブジェクトを取得する前に、Hibernate Search が強制的にキャッシュを調べます。

例14.43 クエリーを使用する前の 2 次キャッシュのチェック

FullTextQuery query = session.createFullTextQuery(luceneQuery, User.class);
query.initializeObjectWith(
    ObjectLookupMethod.SECOND_LEVEL_CACHE,
    DatabaseRetrievalMethod.QUERY
);
ObjectLookupMethod は、オブジェクトをデータベースから取得せずに簡単にアクセスできるかどうかを確認するストラテジーを定義します。その他のオプションは以下のとおりです。
  • ObjectLookupMethod.PERSISTENCE_CONTEXT は、一致する多くのエンティティーが永続コンテキストにすでにロードされている場合に使用されます (Session または EntityManager にロードされている場合)。
  • ObjectLookupMethod.SECOND_LEVEL_CACHE は永続コンテキストをチェックし、2 次キャッシュを確認します。
2 次キャッシュで検索するには、以下を設定します。
  • 2 次キャッシュを正しく設定およびアクティブ化します。
  • 関連するエンティティーの 2 次キャッシュを有効にします。これは、@Cacheable などのアノテーションを使用してを行います。
  • SessionEntityManager、または Query のいずれかの 2 次キャッシュ読み取りアクセスを有効にします。Hibernate ネイティブ API では CacheMode.NORMAL を使用し、Java Persistence API では CacheRetrieveMode.USE を使用します。
警告
2 次キャッシュ実装が EHCache または Infinispan でない場合、ObjectLookupMethod.SECOND_LEVEL_CACHE は使用しないでください。他の 2 次レベルのキャッシュプロバイダーはこのオペレーションを効率的に実装しません。
DatabaseRetrievalMethod を使用して、以下のようにデータベースからオブジェクトを読み込む方法をカスタマイズします。
  • QUERY (デフォルト) はクエリーのセットを使用して、複数のオブジェクトを各バッチに読み込みます。このアプローチが推奨されます。
  • FIND_BY_ID は、Session を使用して一度に 1 つのオブジェクトをロードします。getまたは EntityManagerfindセマンティック。これは、Hibernate Core がエンティティーをバッチでロードできるようにする、エンティティーにバッチサイズが設定されている場合に推奨されます。
14.3.1.10.7. クエリー時間の制限
Hibernate Guide で、以下のようにクエリーにかかる時間を制限します。
  • 制限を指定して受信する際に例外を発生させます。
  • 時間制限が発生したときに取得する結果の数に制限します。
14.3.1.10.8. 時間制限の例外発生
クエリー使用する時間が定義した時間を超える場合は、QueryTimeoutException が発生します (プログラム API に応じた、org.hibernate.QueryTimeoutException または javax.persistence.QueryTimeoutException)。
ネイティブの Hibernate API を使用する際に制限を定義するには、以下のいずれかの方法を使用します。

例14.44 クエリー実行でのタイムアウトの定義

Query luceneQuery = ...;
FullTextQuery query = fullTextSession.createFullTextQuery(luceneQuery, User.class);

//define the timeout in seconds
query.setTimeout(5);

//alternatively, define the timeout in any given time unit
query.setTimeout(450, TimeUnit.MILLISECONDS);

try {
    query.list();
}
catch (org.hibernate.QueryTimeoutException e) {
    //do something, too slow
}
ThegetResultSize()iterate()scroll()メソッド呼び出しが終了するまでのタイムアウトを尊重します。その結果、Iterable または ScrollableResults は、タイムアウトを無視します。さらに、explain()このタイムアウト期間は尊重されません。この方法は、デバッグに使用され、クエリーのパフォーマンス低下の原因をチェックします。
以下は、Java Persistence API (JPA) を使用した実行時間を制限する標準的な方法です。

例14.45 クエリー実行でのタイムアウトの定義

Query luceneQuery = ...;
FullTextQuery query = fullTextEM.createFullTextQuery(luceneQuery, User.class);

//define the timeout in milliseconds
query.setHint( "javax.persistence.query.timeout", 450 );

try {
    query.getResultList();
}
catch (javax.persistence.QueryTimeoutException e) {
    //do something, too slow
}
重要
サンプルコードは、クエリーが指定の結果量で停止することを保証しません。
Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

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

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

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

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

会社概要

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

© 2024 Red Hat, Inc.