2011-05-25 4 views
10

大きな(500 000)ではないテーブルの一部の11文字列またはテキストフィールドでILIKEを実行しているクエリがありますが、明らかに大きすぎるILIKEでは検索クエリのラウンドは20秒です。データベースはポストグルです8.4Hibernate Search、Luceneまたはその他の代替手段?

私はこの検索をもっと速くするために実装する必要があります。

何が私の心に来た:

  1. 私が検索する必要があるすべての列から組み立て追加TVECTOR列を作り、その上にフルテキストインデックスを作成しました。全文検索はかなり速かった。しかし...私はこのTVECTORタイプを私の.hbmsにマップすることはできません。だから、このアイデアは消えてしまった(いずれにしても、私はそれを一時的な解決策としてもっと捉えた)。

  2. 休止状態の検索。 (これについて初めて聞いたことがありますが)これは期待しているようですが、私は新しいAPIを使いたいと思っていないので、経験豊富な意見が必要です。いずれの場合においても

  3. のLucene

、これは、この表で今起こっている、しかし、私は解決策には、より一般的な、フルテキスト検索に関連する将来のケースに適用されるようにしたいと思います。

すべてのアドバイスをいただきありがとうございます。

ありがとう

答えて

12

私は、HibernateとLuceneの間の非常に使いやすいブリッジを提供するHibernate Searchを強くお勧めします。あなたがここで両方を使用することを思い出してください。検索できるドメインクラスのプロパティに注釈を付けるだけです。次に、Hibernate Searchを検索するために有効になっているエンティティを更新/挿入/削除すると、関連するインデックスが更新されます。これは、データベースの変更が発生したトランザクションがコミットされた場合にのみ発生します。つまり、ロールバックされた場合、インデックスは破損しません。

だからあなたの質問に答えるために:

  1. はい、あなたが特定のテーブル上のインデックスの特定の列をすることができます。また、フィールドの内容をトークン化してフィールドの一部に一致させることもできます。

  2. これはまったく使用するのは難しいことではなく、検索するプロパティを簡単に決めるだけです。インデックスを保持する場所をHibernateに指示します。 EntityManager/Sessionインタフェースを使用して、検索したエンティティをロードできます。

+0

説明がありません。もう少し短い質問です。いくつかの文字列フィールドで検索できます。他のすべてのフィールドをインデックスにも格納するのは意味がありますが、検索可能にならない場合は、そこからオブジェクトを取得する、またはIDSを取得してデータベースに取得する必要があります? – Julia

+0

@Julia検索したいフィールドにのみインデックスを付ける必要があります。 Hibernate Searchに、インデックスされたエンティティの@DocumentId(@Id)が何であるかを伝えます。 HibernateはこのIDを使用して、データベース(またはセッションキャッシュ)からエンティティを取得します。実際には、Hibernate Searchは検索文字列を取り、その検索に一致するドメインエンティティを返します。きちんとした? –

+0

本当によかった! – Julia

0

私はCompassをお勧めします。 Luceneの上に構築されたオープンソースプロジェクトで、Luceneよりも簡単なAPIを提供しています。 SpringやHibernateなどの多くの一般的なJavaライブラリやフレームワークとうまく統合されています。

0

過去にLuceneを使用してデータベーステーブルのインデックスを作成しました。ソリューションは素晴らしいですが、インデックスを維持する必要があることを思い出してください。どちらの場合も、オブジェクトが永続化されるたびに、またはLuceneインデックスにデータベーステーブルをダンプするデーモンインデクサがあるたびに、インデックスを更新します。

Solrとお考えですか?これはLuceneの上に構築され、DBおよびRest APIからの自動インデックス作成を提供します。

+0

thanx。私たちはすでに文書索引付けにluceneを使用していますので、同じ図書館にもっとスティックするように教えました。たとえば、Luceneではオブジェクトの関係を索引付けすることができますか?私はテーブル全体を索引付けする必要がありますか、またはメインテーブルとその関係の中から必要な特定のカラムを作成できますか? – Julia

+0

私のやり方は、JOINSでSELECTクエリを使用してデータのフラットな構造を作成し、インデクサーを実行できるようにすることでした。これが一つのアプローチです。また、ストアドプロシージャを使用して、インデックス作成の目的で使用される特別なテーブルにデータをフラット化することもできます。 –

0

すべてのプロジェクトはLuceneに基づいています。非常に高度な機能を実装したい場合は、Luceneを直接使用することをお勧めします。そうでない場合は、Solrを使用することができます。このAPIは、DBからの索引作成および検索に役立つluceneの上にある強力なAPIです。

+0

あまりにも高度な機能は必要ないと思いますが、これまで使用していなかった新しいライブラリを使用しないようにしたいと考えています。あなたがなぜSolrをお勧めしているのか理解できていないのか分かりません。もう少し明確にしてもらえますか?ありがとう!!! – Julia

+0

私はあなたに例を挙げます.Webサーバーへのhttp呼び出しを行う必要があります。 javaには、それを行うのに役立つソケットライブラリがありますが、apache commons http clientというより良い方法があります。プロトコルを実装するライブラリが組み込まれています。 Solrの場合、インデックスを管理するためのAPIが組み込まれています。簡単にデータベースを統合してフルテキスト検索ができ、サーブレットコンテナの実行が可能です。 –

6

すでにHibernateとLuceneを使用しているので、Hibernate Searchは優れた選択肢です。

主にHibernate Searchは、データが変更されたときにLuceneインデックスを更新するメカニズムと、Luceneインデックスに対する検索を簡略化するためにHibernateについて既に知っていることを最大化するメカニズムです。

インデックスを作成する各エンティティの特定のフィールドを指定し、必要に応じて複数のタイプのインデックスを追加することができます(例:ステムとフルテキスト)。また、関連付けのためにグラフを索引付けすることもできるので、Search/Luceneを通してかなり複雑な照会を行うことができます。

私は、テキストの重い検索のためにHibernate Searchに頼っているが、より伝統的な検索と、結果表示のための複雑なオブジェクトグラフの水和のために、普通の古いHibernateに戻すことが最良であることを発見した。

0

1年前に私はコンパスをお勧めしました。それは、それが何をしているのか良くて、技術的には私が開発し維持しているアプリケーションではうまくいっています。

しかし、ElasticSearchに切り替える努力をしてコンパスにはこれ以上の開発はありません。そのプロジェクトのウェブサイトから、ビッグタイムの準備ができているのか、それとも実際には生きているのかは全く判断できません。

私はそれが私に良い感じを与えていない休止状態に切り替えるんだが、その移行はまだ初期段階にあるので、私はしばらくの間、判断を予約します。

関連する問題