ファイル内の全文検索の検討メモ

テキストファイル、wordやExcelなどのOfficeファイル、PDFなど様々なファイルを登録しておいて、
登録したファイルの中の文章から検索を行いたいというような話です。
今はApache Solrとかが流行ってますが、
アプリケーションの導入となると何かとハードルが高いので、
手持ちの材料で何かできないかというメモです。
雑です。

というわけで、まずはOracle Textについて調べてみた。
Oracle Textは全文検索の仕組みをOracleに載せたもの。
例えば、文章の中に"田中△一郎"、"田中・一郎"、"田中一郎" みたいに同じ単語でも間にスペースや記号があったりしても、"田中一郎"という検索ワードで一律ヒットさせたいというようなもの。
最近のバージョンであれば製品に最初から入っている(インストールの仕方によっては入ってない場合もあるが追加インストールできる)

とりあえず試してみるのに、参考にしたのはこの辺りの資料

Oracle Textの全文検索OracleらしくSQLのwhere条件にCONTAINS('列名','検索ワード')という条件を書く事で行う。そのためには、

  • 特定のテーブルの列(不定形の文章を入れるような列)にOracleText用のIndexを作る。
  • そのIndexには、構文解析の設定が必要(例, N-GRAM方式のJAPANESE_VGRAM_LEXERや、形態素解析のJAPANESE__LEXERなど)
  • ただしテーブルの挿入や更新と同時にそのIndexは更新されないため、定期的にIndexの同期をプロシージャで行う必要がある。(普通のIndexと比べると処理が重いためか)

などを行う必要がある。

とはいえ、これはテーブルの列について全文検索する設定なので、ファイルの場合はどうするの?
というと、上記のIndexの設定で、特定のディレクトリやURLなどを設定することで
その場所にあるファイルからテキストを自動で抽出してIndexを作成するようである。
それはそれで面倒なので、テーブルにBLOBの列を作成して、そこに全文検索のIndexを作って、
ファイルのバイナリを登録したらどうなるのかを試してみたら、
あっさりとバイナリからファイルのテキストを抽出してIndexを作ってくれました。
全部は試していませんが、ファイルの形式(ワードとかエクセルとか)を識別しますので、
それなりに使えるかと思います。
ただし、Officeのテキストボックスの中の文章は読み込めないようでした。
(Indexの定期的な同期など、考えないといけない事は色々ありますが)

補足として、検索条件にヒットした文章のどこがヒットしたのかを明示したいこともあるかと思います。
そういう場合は、別途プロシージャを使う必要があります。
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/text.102/B19214-01/cdocpkg.htm
にある、CTX_DOC.プロシージャに色々と種類があり、例えば、
CTX_DOC.MARKUP というプロシージャで、検索条件にヒットした文章の中の、
ヒットした箇所を、<<< と >>> で囲んで表示できます。
CTX_DOC.MARKUP には、全文検索のIndex名や、レコードのユニークキー、検索条件などを引数として渡す必要があるので、
検索してヒットしたレコード1件ずつに対して、MARKUPを行っていくという手順になります。


非常に雑だと自分でも思いますが、とりあえず使ってみた結果はこんな感じでした。
Oracleが手元にあるなら、とりあえずやってみてもいいかもしれませんが、
Indexの再作成や、ちょっと手の込んだことをするとなるとプロシージャを多用したりするので、そこは割と面倒だと感じました。
ファイルの抽出でOfficeのテキストボックを抽出できないのはちょっと残念なので、
別のライブラリも試す予定。