読者です 読者をやめる 読者になる 読者になる

kagamihogeの日記

kagamihogeの日記です。

Oracle TextでSQLでPDFを全文検索

Oracle DBA & Developer Days 2011:セッション動画SQL文でできる!Oracle Databaseの全文検索機能「Oracle Text」の活用法を見て書いているエントリです。

Oracle Textの主な特徴を先のPDF資料から抜粋するとこんな感じ。

Oracle Databaseカーネルで実装された全文検索エンジン
SQLのみで全文検索アプリケーションを開発可能
Expess Edition で利用可能
索引作成対象の列として指定可能なデータ型は、CHAR、VARCHAR、VARCHAR2、BLOB、CLOB、BFILE、XMLType、URIType のいずれか

SQL文でできる!Oracle Databaseの全文検索機能「Oracle Text」の活用法 から抜粋

こんな環境でやりました

やったこと

基本的には、先のPDF資料に沿ったことをやっていきます。ただし、VARCHARの検索だけじゃおもんないな〜ってことで、全文検索対象をPDFファイルを想定して進めていきます。

まず、PDFファイルの実物を置くためのディレクトリ・オブジェクトを作成。

CREATE DIRECTORY PDFTEST AS 'C:\pdftest';

下記は環境によっては不要かもだけど、上で作成したディレクトリ・オブジェクトに権限を付与しておく。

GRANT ALL ON DIRECTORY "PDFTEST" to KAGAMIHOGE;

PDFファイルの置いてあるディレクトリにサンプル用に適当なファイルを置く。今回は下記3つのファイルを借用。

PDFファイルを持つテーブルを作成。今回はBLOBじゃなくてBFILEを使用してます。理由は、試しにやる分にはOracle内にデータ持つ必要を感じなかったのと、なによりSQLでナマのPDFファイルを全文検索にするってのをやってみたかったので。

CREATE TABLE BFILE_TEST 
(
  BFILEA BFILE 
);

テーブルに行追加。

INSERT INTO BFILE_TEST VALUES (BFILENAME('PDFTEST', 'map_tokyo.pdf'));
INSERT INTO BFILE_TEST VALUES (BFILENAME('PDFTEST', 'c-3-wlstips-1448373-ja.pdf'));
INSERT INTO BFILE_TEST VALUES (BFILENAME('PDFTEST', 'c-10-oracletext-1448393-ja.pdf'));

これでサンプルデータの準備は完了。

次に、全文検索用のプリファレンスとインデックスを作成。

DECLARE
BEGIN
CTX_DDL.CREATE_PREFERENCE('jvl','JAPANESE_VGRAM_LEXER');
END;
CREATE INDEX textidx ON BFILE_TEST (BFILEA)
  INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('LEXER jvl');

これで全文検索の準備完了。細かいチューニングとかはともかく、ひとまずコレでSQLでPDFファイルを全文検索する準備はOK

下記のSQL全文検索用のトークンが参照できる。textidxはさっき作ったインデックスを指定します。

SELECT TOKEN_TEXT FROM DR$textidx$I ORDER BY TOKEN_TEXT;

というわけで検索してみます。

SELECT BFILEA FROM BFILE_TEST WHERE CONTAINS (BFILEA, '新宿') > 0;

1件ヒット。とりあえず、PDFファイルの中を見て検索はしてくれてるのが確認できました。

SELECT BFILEA FROM BFILE_TEST WHERE CONTAINS (BFILEA, 'アクセスの増加に伴い、H/W リソースが') > 0;

これも1件ヒット。テーブルにBFILEカラムしかないんで本当に欲しい検索結果が出てきてるのかちと不透明ですが……まぁ今回は深く考えないことにする。

Oracle Textは「基本的に、全角・半角・大文字・小文字の区別なし」てことなのでコレを試してみる。

SELECT BFILEA FROM BFILE_TEST WHERE CONTAINS (BFILEA, 'weblogic server') > 0;

2件ヒット。

次に、検索文字列をすべて大文字にしてみる。

SELECT BFILEA FROM BFILE_TEST WHERE CONTAINS (BFILEA, 'WEBLOGIC SERVER') > 0;

2件ヒット。

次に、検索文字列を全角カタカナにして検索してみる。

SELECT BFILEA FROM BFILE_TEST WHERE CONTAINS (BFILEA, 'WEBLOGIC SERVER') > 0;

2件ヒット。コレは若干驚かされたが……「基本的に全角・半角の区別なし」ってところの動きが確認できました。