Sunday, February 1, 2009

Oracleで全文検索[Oracle Text]

Oracleで全文検索[Oracle Text] ctxsys
http://www.bnote.net/oracle/oracletext.shtml

Oracle9iで複数項目にまたがる全文検索を行います。

環境:Oracle9i[Release 9.2.0.1.0]
Oracleで全文検索に必要だった設定等

1.Oracle Text

2.データベースのキャラクタセットをJA16SJIS、JA16EUC、UTF8のいずれかで作成する。

3.対象となるテーブルにダミー項目を追加する。(微妙)
Oracle全文検索環境構築

日本語のテキストからトークンを抽出するには、レクサーにJAPANESE_VGRAM_LEXERまたは、JAPANESE_LEXERを指定します。この場合、Oracle9iでは、キャラクタセットがJA16SJIS、JA16EUC、UTF8のいずれかである必要があるので、DataBaseをUTF8で再構築しました。

今回は、puccaというユーザーを作り次のようなテーブルを作成します。

CREATE TABLE ITS
(
ID NUMBER(10,0) NOT NULL,
PLAN_START_DATE VARCHAR2(8),
PLAN_COMP_DATE VARCHAR2(8),
PRIORITY VARCHAR2(12),
TASK VARCHAR2(1000) NOT NULL,
MEASURE VARCHAR2(1000),
REMARKS VARCHAR2(128),
REFERENCE VARCHAR2(128),
DMY CHAR(1),
CONSTRAINT PK_ITS PRIMARY KEY (ID) USING INDEX
)

複数項目を対象とするには、テキストの格納方法にMULTI_COLUMN_DATASTOREを指定する必要があります。このMULTI_COLUMN_DATASTORE型のプリファレンスを作成できるのは、CTXSYSユーザのみのためCTXSYSユーザで接続し、全文検索に関わる属性を設定します。

BEGIN
CTX_DDL.CREATE_PREFERENCE('multi_item', 'MULTI_COLUMN_DATASTORE');
CTX_DDL.SET_ATTRIBUTE('multi_item', 'columns', 'TASK,MEASURE,REMARKS');
CTX_DDL.CREATE_PREFERENCE('japan_lexer', 'JAPANESE_LEXER');
END;

上記例では、TASK,MEASURE,REMARKSの3つの項目を対象としています。

次に索引を作成します。

CREATE INDEX
pucca.ITS_IDX on pucca.ITS(DMY)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS('datastore multi_item lexer japan_lexer');

以上で設定が完了します。
索引の同期化と最適化

Oracle Textでは、索引として何らかのトークンに分けて格納されます。しかし、テーブルにINSERTしただけでは、索引が作成されないようです。

索引を作成するには、索引の同期化を行います。

BEGIN
-- 引数にINDEX名を指定
CTX_DDL.SYNC_INDEX('ITS_IDX');
END;

索引が作成されたかは、次のSELECT文で確認することができます。テーブル名は、DR$インデックス名$I になっています。

select token_text from DR$ITS_IDX$I;


TOKEN_TEXT
-----------
システム


作成
管理
資料

INSERTと同様にUPDATEやDELETEを行っても上記トークン表は更新されません。そこで、変更を反映させるために索引の最適化を行います。

BEGIN
CTX_DDL.OPTIMIZE_INDEX('ITS_IDX','FULL');
END;

索引の最適化には、3つの方法があり第二引数に次のいずれかを指定します。
・完全(FULL)
・高速(FAST)
・トークン(TOKEN)
更新と検索

更新を行う場合、ダミー項目(DMY)を更新しないと索引の同期処理を行っても索引が更新されません。

テーブルから検索を行う場合、WHERE句でCONTAINS演算子を使用します。

SELECT * FROM ITS WHERE CONTAINS(DMY,'資料') > 0

No comments: