第14章 Hibernate Search
14.1. Hibernate Search の使用 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
14.1.1. Hibernate Search について リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Hibernate Search は、Hibernate アプリケーションに完全なテキスト検索機能を提供します。これは、全文、あいまい、位置情報検索などの SQL ベースのソリューションには適していないアプリケーションの検索に適しています。Hibernate Search は Apache Lucene を全文検索エンジンとして使用しますが、メンテナンスのオーバーヘッドを最小限に抑えるように設計されています。設定が完了したら、インデックス、クラスタリング、およびデータ同期は透過的に維持されるため、ビジネス要件を満たすことができます。
14.1.2. Hibernate Search を使用する最初の手順 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
アプリケーションの Hibernate Search の使用を開始するには、以下のトピックに従います。
- Hibernate Search を設定するには、JBoss EAP 『管理および設定ガイド』 の 『設定』 を参照してください。
14.1.3. Maven を使用した Hibernate Search の有効化 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Maven プロジェクトで以下の設定を使用し、
hibernate-search-orm 依存関係を追加します。
14.1.4. アノテーションの追加 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
ここでは、書籍の詳細を含むデータベースの例を見てみましょう。アプリケーションに Hibernate 管理クラス
example.Book および example.Author が含まれ、アプリケーションにフリーテキスト検索機能を追加して、書籍の検索を有効にする場合。
例14.1 Hibernate Search 固有のアノテーションを追加する前のエンティティーブックおよび作成者
これを行うには、
Book クラスおよび Author クラスにアノテーションをいくつか追加する必要があります。最初のアノテーション @Indexed は Book にインデックス可能 (indexable) のマークを付けます。デザイン上、Hibernate Search は未認証の ID をインデックスに保存し、特定のエンティティーのインデックスの一意性を確保します。@DocumentId は、この目的に使用するプロパティーをマークし、ほとんどの場合はデータベースのプライマリーキーと同じです。@DocumentId アノテーションは、@Id アノテーションが存在する場合は任意です。
次に、検索可能にするフィールドには、そのようにマークを付ける必要があります。この例では、
title と subtitle で始まります。両方に、@Field アノテーションを付けます。パラメーター index=Index.YES は、テキストが確実にインデックス化されるようにします。一方、analyze=Analyze.YES は、デフォルトの Lucene アナライザーを使用してテキストが分析されるようにします。通常、分析とは個別の単語に文章を分け、'a' や `the'.などの一般的な単語を除外できる可能性があることを意味します。アナライザーについてもう少し後ほど説明します。@Field で指定する第 3 のパラメーター store=Store.NO は、実際のデータがインデックスに保存されないようにします。このデータがインデックスに保存されているかどうかや、そのデータを検索する機能がないかどうかです。Lucene の観点からは、インデックスが作成されてからデータを保持する必要はありません。これを保存する利点は、projections を介してそれを取得することです (「プロジェクション」 を参照してください)。
Hibernate Search は projections なしで、クエリー基準に一致するエンティティーのデータベース識別子を見つけるためにデフォルトで Lucene クエリーを実行し、これらの識別子を使用してデータベースから管理オブジェクトを取得します。projection については、状況に応じてまたは対照的に決定する必要があります。管理オブジェクトを返す一方で、オブジェクト配列のみを返すため、デフォルトの動作が推奨されます。
Index=Index.YES, analyze=Analyze.YES および store=Store.NO はこれらのパラメーターのデフォルト値であるため、省略できることに注意してください。
まだ説明されていない別のアノテーションは
@DateBridge です。このアノテーションは、Hibernate Search の組み込みフィールドブリッジのいずれかになります。Lucene インデックスは文字列ベースです。このため、Hibernate Search はインデックス化されたフィールドの値タイプを文字列 (またはその逆) に変換する必要があります。事前定義されたブリッジの範囲が提供されます。これには、java.util.Date を指定の解決が含まれる String に変換する DateBridge が含まれます。詳細は、「ブリッジ」 を参照してください。
これにより、
@IndexedEmbedded が残ります。 このアノテーションは、所有するエンティティーの一部として、関連付けられたエンティティー (@ ManyToMany、@ * ToOne、@ Embedded、および @ElementCollection) にインデックスを付けるために使用されます。これは、Lucene インデックスドキュメントがオブジェクト関係について不明なフラットデータ構造であるため必要になります。作成者の名前を確実に検索できるようにするには、名前を書籍の一部としてインデックス化する必要があります。@IndexedEmbedded のほかに、インデックスに含める関連エンティティーのフィールドすべてを @Indexed でマークする必要があります。詳細は、「埋め込みおよび関連オブジェクト」 を参照してください。
現在、これらの設定で十分です。エンティティーマッピングの詳細については、を参照してください。「エンティティーのマッピング」。
例14.2 Hibernate Search アノテーションの追加後のエンティティー
14.1.5. インデックス化 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Hibernate Search は、Hibernate Core を介して永続化、更新、または削除されるすべてのエンティティーを透過的にインデックス化します。ただし、データベースにすでに存在するデータの初期 Lucene インデックスを作成する必要があります。上記のプロパティーとアノテーションを追加したら、book の初期バッチインデックスをトリガーする時間になります。これは、以下のコードスニペットのいずれかを使用して実行できます (「インデックスの再構築」 を参照してください)。
例14.3 Hibernate セッションを使用してデータにインデックスを付ける
FullTextSession fullTextSession = org.hibernate.search.Search.getFullTextSession(session); fullTextSession.createIndexer().startAndWait();
FullTextSession fullTextSession = org.hibernate.search.Search.getFullTextSession(session);
fullTextSession.createIndexer().startAndWait();
例14.4 JPA を使用したデータのインデックス作成
EntityManager em = entityManagerFactory.createEntityManager(); FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em); fullTextEntityManager.createIndexer().startAndWait();
EntityManager em = entityManagerFactory.createEntityManager();
FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
fullTextEntityManager.createIndexer().startAndWait();
上記のコードを実行した後は、
/var/lucene/indexes/example.Book に Lucene インデックスが表示されるはずです。Luke でこのインデックスを調べてください。HibernateSearch がどのように機能するかを理解するのに役立ちます。
14.1.6. 検索 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
検索を実行するには、Lucene API (「Lucene API を使用した Lucene クエリーの構築」) または Hibernate Search query DSL (「Lucene クエリーの構築」) のいずれかを使用して Lucene クエリーを作成します。
org.hibernate.Query にクエリーをラップし、Hibernate API から必要な機能を取得します。以下のコードは、インデックスフィールドに対するクエリーを準備します。コードを実行すると、Book の一覧が返されます。
例14.5 Hibernate Search セッションを使用した検索の作成および実行
例14.6 JPA を使用した検索の作成と実行
14.1.7. アナライザー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
インデックス化された Book エンティティーのタイトルが
Refactoring: Improving the Design of Existing Code で、refactor、refactors、refactored、refactoring のクエリーに必要だとします。インデックス化および検索を行う際にワードステミングを適用する Lucene でアナライザークラスを選択します。Hibernate Search は、アナライザーを設定するためのいくつかの方法を提供します (を参照)。「デフォルトの Analyzer とクラスによる Analyzer」詳細については):
- 設定ファイルに
analyzerプロパティーを設定します。指定されたクラスがデフォルトのアナライザーになります。 - エンティティーレベルで
アノテーションを設定します。@Analyzer - フィールドレベルで
@アノテーションを設定します。Analyzer
完全修飾クラス名または使用するアナライザーを指定するか、
@Analyzer アノテーションとともに @AnalyzerDef アノテーションで定義されているアナライザーを確認します。Solr アナライザーフレームワークとそのファクトリーは、後者のオプションに使用されます。ファクトリークラスの詳細は、Solr JavaDoc を参照するか、Solr Wiki (http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters) の該当するセクションを参照してください。
この例では、
StandardTokenizerFactory が、LowerCaseFilterFactory と SnowballPorterFilterFactory の 2 つのフィルターファクトリーによって使用されています。トークンライザーは、英数字とハイフンで単語を分割しますが、メールアドレスとインターネットのホスト名は維持します。標準トークンは、これおよびその他の一般的な操作に適しています。小文字フィルターはトークンのすべての文字を小文字に変換し、snowball フィルターは言語固有のステミングを適用します。
Solr フレームワークを使用する場合は、任意の数のフィルターでトークンを使用します。
例14.7 @AnalyzerDef および Solr Framework を使用した Analyzer の定義および使用
@AnalyzerDef を使用してアナライザーを定義し、@Analyzer を使用してエンティティーおよびプロパティーに適用します。この例では、customanalyzer は定義されますが、エンティティーには適用されません。アナライザーは title および subtitle プロパティーのみに適用されます。アナライザーの定義はグローバルです。エンティティーのアナライザーを定義し、必要に応じて他のエンティティーの定義を再利用します。