« Hibernate Validatorを使う | メイン | 開発の現場 VOL.008 »

Hibernate Searchを触る

Hibernate Searchは、アノテーションによってドメインモデルの索引を生成し、テキストのクエリーからドメインモデルのエンティティを取得することができるようにしたプロダクトです。Hibernate Searchは、検索エンジンにApache Luceneを使っています。Hibernate Searchもこのたび晴れてHibernateのTOPプロジェクトに昇格したプロダクトです。(まだベータ版ですが)

ということでHibernate Validatorを触ったりHibernate Shardsを触ったりしたついでに少しだけ触ってみます。Hello Worldレベルです。

  1. 必要なライブラリ
  2. 面倒なので、前回のHibernate Validatorを使ったときのものを流用することにします。これに加えて必要なものは

    • lucene-core-2.1.0.jar
    • hibernate-search.jar

    です。どちらもHibernate Searchのアーカイブの中に含まれています。JMSを使うのであればjms.jarも要りますが今回は使いません。なおLuceneが2.1.0よりも古いと動かなくなったみたいなので注意です。

  3. エンティティクラス
  4. 前回のHibernate Validatorを使ったときのエンティティを少しだけ改造します。

    @Entity
    @Indexed
    public class Customer implements Serializable {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @DocumentId
     public int id;
     @NotNull
     @Length(max = 10)
     @Field(index = Index.TOKENIZED, store = Store.YES)
     public String name;
     @Range(min = 0, max = 100)
     public int age;
     @Email
     public String email;
     @Past
     public Date birthday;
    }

    赤字のところしか変えていません。

  5. 定義ファイル
  6. hibernate.cfg.xmlはこんな感じです。Hibernate Search用に変えている部分は省略しています。

    <hibernate-configuration>
     <session-factory>
      ・・・
      <property name="hibernate.search.default.directory_provider">
       org.hibernate.search.store.FSDirectoryProvider
      </property>
      <property name="hibernate.search.default.indexBase">C:\Indexes</property>
      <mapping package="net.grandnature.example.entity"/>
      <mapping class="net.grandnature.example.invoice.entity.Customer"/>
      <event type="post-update">
       <listener class="org.hibernate.search.event.FullTextIndexEventListener"/>
      </event>
      <event type="post-insert">
        <listener class="org.hibernate.search.event.FullTextIndexEventListener"/>
      </event>
      <event type="post-delete">
        <listener class="org.hibernate.search.event.FullTextIndexEventListener"/>
      </event>
     </session-factory>
    </hibernate-configuration>

    Luceneによって生成されるインデックスのファイル達がC:\Indexesに保存される設定です。

  7. エンティティを登録してみる
  8. Sessionをそのまま使うのではなくFullTextSessionを取得してそれを使うようにします。それ以外は普通です。


    SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
    Session session = sessionFactory.openSession();
    FullTextSession fullTextSession = Search.createFullTextSession(session);
    Transaction tx = fullTextSession.beginTransaction();
    Customer customer = new Customer();
    customer.name = "KIDA Taro";
    customer.age = 76;
    customer.email = "kida@example.com";
    DateFormat parser = DateFormat.getDateInstance();
    ex.birthday = parser.parse("1930/12/06");
    fullTextSession.save(ex);
    tx.commit();
    fullTextSession.close();

    これを実行してエンティティがRDBに永続化されると、Luceneのインデックスも同時に生成されています。C:\Indexesの中にそれらしいファイルが出来ていると思いますが、それらがLuceneのインデックスファイルです。

  9. 検索してみる
  10. SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
    Session session = sessionFactory.openSession();
    FullTextSession fullTextSession = Search.createFullTextSession(session);
    BooleanQuery booleanQuery = new BooleanQuery();
    booleanQuery.add(new PrefixQuery(new Term("name", "Kida")),BooleanClause.Occur.SHOULD);
    Query fullTextQuery = fullTextSession.createFullTextQuery(booleanQuery);
    Iterator result = fullTextQuery.iterate();
    while (result.hasNext()) {
     Customer customer = (Customer) result.next();
     System.out.printf("%d - %s%n", customer.id, customer.name);
    }
    ・・・

    BooleanQuery、PrefixQuery、BooleanClause、TermはLuceneのクラスです。QueryはHibernateのQueryです。こんな感じでクエリーから該当するHibernateのエンティティのインスタンスを取得できます。

トラックバック

このエントリーのトラックバックURL:
http://www.grandnature.net/bin/mt-tb.cgi/34

コメントを投稿

About

2007年04月11日 17:38に投稿されたエントリーのページです。

ひとつ前の投稿は「Hibernate Validatorを使う」です。

次の投稿は「開発の現場 VOL.008」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。