4 Oracle Textの索引の作成
Oracle Text索引を作成する方法を学習します。
この章のトピックは、次のとおりです:
4.1 Oracle Text索引の作成手順の概要
Oracle Textでは、CONTEXT
、CTXCAT
およびCTXRULE
タイプの索引を作成できます。
ASYNCHRONOUS_UPDATE
パラメータ文字列オプションの使用によって古い索引エントリを維持して元の内容を検索することもできます。
デフォルトでは、システムはドキュメントがテキスト列に格納されるとみなします。この要件が満たされていると、プリファレンスを明示的に指定せずに、SQL文CREATE
INDEX
を使用して、Oracle Text索引を拡張可能な索引タイプCONTEXT
として作成できます。システムでは、言語、テキスト列のデータ型、およびドキュメントの形式が自動的に検出されます。次に、索引プリファレンスが設定されます。
Oracle Textの索引を作成するには:
-
(オプション)デフォルトを使用しない場合は、カスタムの索引プリファレンス、セクション・グループまたはストップリストを指定します。次の表は、これらの索引クラスを説明しています。
-
(オプション)カスタム・プリファレンス、セクション・グループまたはストップリストを作成します。
-
CREATE
INDEX
SQL文を使用してOracle Text索引を作成します。索引に名前を付け、必要に応じてプリファレンスを指定します。
4.2 プリファレンスの作成
必要に応じて、カスタムの索引プリファレンスを作成してデフォルトをオーバーライドできます。ファイルの格納場所やドキュメントのフィルタ処理方法などの索引情報を指定するには、プリファレンスを使用します。プリファレンスを作成した後、属性を設定します。
関連項目:
4.3 セクション検索の例: HTMLセクションの作成
HTMLやXMLのように、ドキュメントに内部構造がある場合は、索引付け操作前に埋込みタグを使用してドキュメントのセクションを定義できます。このアプローチによって、WITHIN
演算子を使用してセクション内で問合せができます。セクションは、セクション・グループの構成要素として定義します。
4.4 ストップワードおよびストップリストの使用
ストップワードとは、英語のthisやthatなど、索引付け対象外の単語のことです。
システムでは各言語のストップリストが用意されています。デフォルトでは、索引付け時に使用言語に対して、Oracle Textのデフォルトのストップリストが使用されます。
デフォルトのCTXSYS.DEFAULT_STOPLIST
を編集するか、次のPL/SQLプロシージャを使用して独自のリストを作成できます。
-
CTX_DDL.CREATE_STOPLIST
-
CTX_DDL.ADD_STOPWORD
-
CTX_DDL.REMOVE_STOPWORD
CREATE INDEXのPARAMETERS句に、カスタムのストップリストを指定します。
また、索引を作成した後で、ALTER INDEX
文でストップワードを動的に追加することもできます。
4.5 CONTEXT索引の作成
CONTEXT
索引タイプは、Microsoft Word、HTMLまたはプレーン・テキストのような形式の大量のまとまったドキュメントを索引付けする場合に最適です。CONTEXT
索引では、様々な方法で索引をカスタマイズすることもできます。ドキュメントはテキスト表にロードする必要があります。
この項には、次の項目が含まれます。
4.5.1 CONTEXT索引およびDML
CONTEXT
索引は、トランザクション・ベースでは更新されません。レコードを削除すると、索引は即時に変更されます。つまり、変更を行った瞬間からセッションはレコードを検索しなくなり、コミット後には他のユーザーはレコードを検索できなくなります。挿入と更新の場合、索引の同期化が行われるまで、新しい情報はテキスト検索には表示されません。したがって、元表で挿入または更新を行う場合、CTX_DDL.SYNC_INDEX.
を使用して明示的に索引を同期化する必要があります
関連項目:
「索引の同期化」
4.5.2 「デフォルトのCONTEXT索引例」
次の文は、docs
表内のtext
列にmyindex
というデフォルトのCONTEXT
索引を作成します。
CREATE INDEX myindex ON docs(text) INDEXTYPE IS CTXSYS.CONTEXT;
パラメータを明示的に指定せずにCREATE INDEX
文を使用すると、すべての言語に対してシステムのデフォルト動作が次のようになります。
-
索引付けされるテキストは、テキスト列に直接格納されるとみなします。テキスト列の型は、
CLOB
、BLOB
、BFILE
、VARCHAR2
またはCHAR
になります。 -
列型を検出し、バイナリの列型(
BLOB
およびBFILE)に対してフィルタ処理を使用します。
ほとんどのドキュメント形式がフィルタ処理でサポートされています。列がプレーン・テキストの場合、システムはフィルタ処理を使用しません。 -
データベース設定で指定した言語に対するデフォルトのストップリストを使用します。ストップリストは、索引付け時にシステムが無視するワードを識別します。
デフォルトの索引付け動作は、プリファレンスをカスタマイズし、そのプリファレンスをCREATE
INDEX
のパラメータ文字列に指定することによって、いつでも変更できます。
関連項目:
AUTO_FILTER
フィルタを使用するための環境の構成についてさらに学習するには、『Oracle Text リファレンス』を参照してください
4.5.3 ALTER INDEXおよびCREATE INDEXによる索引の追加的な作成
ALTER
INDEX
文およびCREATE
INDEX
文は、CONTEXT
グローバル索引の追加的な作成をサポートします。
-
グローバル索引の場合、
CREATE
INDEX
を使用してREBUILD
句のREPLACE
パラメータでNOPOPULATE
キーワードをサポートします。これにより、索引を追加的に作成できます。このキーワードは、索引付け処理を連続的に実行するのが困難な大規模なインストールでOracle Text索引を作成する場合に便利です。 -
ローカル索引パーティションについて、
ALTER
INDEX
...REBUILD
partition
...parameters
('REPLACE
...')パラメータ文字列を、NOPOPULATE
キーワードをサポートするように修正します。 -
ローカル索引パーティションについては、
CREATE
INDEX
...LOCAL
... (partition
...parameters
('NOPOPULATE
'))がサポートされています。パーティション・レベルのPOPULATE
キーワードまたはNOPOPULATE
キーワードは、索引レベルで指定されたPOPULATE
またはNOPOPULATE
を上書きします。
4.5.4 POPULATE_PENDINGによるCONTEXT索引の追加的な作成
索引付け処理を連続的に実行するのが困難な大規模なインストールの場合、CTX_DDL.POPULATE_PENDING
プロシージャを使用します。このプロシージャでは、索引の作成をより細かく制御することもできます。望ましい方法は、空の索引を作成して、すべてのROWIDを保留キューに配置し、CTX_DDL.SYNC_INDEX.
を介して索引を構築する方法です
このプロシージャにより、元表および表パーティション内のすべてのROWIDが保留中のキューに移入されます。
関連項目:
CTX_DDL.POPULATE_PENDING
の詳細は、『Oracle Textリファレンス』を参照してください。
4.5.5 カスタムのCONTEXT索引例: HTMLドキュメントの索引付け
URLで指定されたHTMLドキュメント・セットを索引付けする場合は、CREATE INDEX
文でシステム定義プリファレンスであるNULL_FILTER
を指定します。
HTML_SECTION_GROUP
を使用するhtmgroup
セクション・グループおよびNETWORK_DATASTORE
を使用するNETWORK_PREF
データストアを指定できます。
begin ctx_ddl.create_preference('NETWORK_PREF','NETWORK_DATASTORE'); ctx_ddl.set_attribute('NETWORK_PREF','HTTP_PROXY','www-proxy.us.example.com'); ctx_ddl.set_attribute('NETWORK_PREF','NO_PROXY','us.example.com'); ctx_ddl.set_attribute('NETWORK_PREF','TIMEOUT','300'); end; begin ctx_ddl.create_section_group('htmgroup', 'HTML_SECTION_GROUP'); ctx_ddl.add_zone_section('htmgroup', 'heading', 'H1'); end;
それから、ドキュメントを索引付けできます。
CREATE INDEX myindex on docs(htmlfile) indextype is ctxsys.context parameters( 'datastore NETWORK_PREF filter ctxsys.null_filter section group htmgroup' );
ノート:
Oracle Database 19c以降、Oracle TextのURL_DATASTORE
型は非推奨になりました。かわりに、NETWORK_DATASTORE
を使用してください。
関連項目
4.5.6 CONTEXT索引例: FILTER BYおよびORDER BYによる問合せ処理
複合問合せで問合せ処理を効率化し応答時間を短縮するため、次の例に示すようにFILTER
BY
句およびORDER
BY
句を使用します。
CREATE INDEX myindex on docs(text) INDEXTYPE is CTXSYS.CONTEXT FILTER BY category, publisher, pub_date ORDER BY pub_date desc;
問合せ時にFILTER
BY
category,
publisher,
pub_date
句を指定したため、Oracle Textではこれらの列上の関連の述語をOracle Text索引の行ソースに入れることも考慮します。
また、問合せに一致するORDER
BY
条件がある場合、応答時間を短縮するために、ORDER
BY
pub_date desc
を指定することで、Oracle Textにより、SORT
をOracle Text索引の行ソースに入れるかどうかが決定されます。
4.6 CTXCAT索引の作成
4.6.2 CTXCATサブ索引とそのコスト
CTXCAT
索引には、索引セットの構成要素として定義したサブ索引が含まれます。1つ以上の列にサブ索引を作成すると、複合問合せのパフォーマンスが向上します。ただし、CTXCAT
索引の作成に要する時間は、その総サイズによって異なります。CTXCAT
索引の総サイズに直接関係する要因は、次のとおりです。
-
索引付けするテキストの合計数
-
索引セットに含まれるサブ索引の数
-
サブ索引を構成する元表の列数
索引セットにコンポーネント索引が多数ある場合も、更新する必要がある索引が多くなるため、挿入、更新および削除操作のパフォーマンスが低下します。
CTXCAT
索引の作成には追加の索引付け時間とディスク領域が必要になるため、索引セットにコンポーネント索引を追加する前に、それぞれのコンポーネント索引によってアプリケーションに提供される問合せパフォーマンス上のメリットを慎重に考慮する必要があります。
ノート:
BASIC_STORAGE
I_ROWID_INDEX_CLAUSE
を使用すると、CTXCAT
索引の作成を高速化できます。この句については、『Oracle Textリファレンス』で説明しています。
4.6.3 CTXCATサブ索引の作成
オンライン・オークション・サイトでは、品目の説明、価格、入札終了日などの情報を格納し、参照する必要があるため、CTXCAT
索引作成のよい例です。
図4-1は、次のスキーマを使用したAUCTION
という表を示しています。
create table auction( item_id number, title varchar2(100), category_id number, price number, bid_close date);
サブ索引を作成するには、サブ索引を格納する索引セットを作成します。
begin ctx_ddl.create_index_set('auction_iset'); end;
次に、入力する可能性がある構造化問合せを特定します。CATSEARCH
問合せ演算子では、必須のテキスト句とオプションの構造化句を使用します。
この例では、すべての問合せにテキスト列であるtitle
列の句が組み込まれています。
構造化句は、次のカテゴリに分類されるとします。
構造化句 | 問合せを満たすサブ索引の定義 | カテゴリ |
---|---|---|
'price < 200' 'price = 150' 'order by price' |
'price' |
A |
'price = 100 order by bid_close' 'order by price, bid_close' |
'price, bid_close' |
B |
構造化問合せ句カテゴリA
構造化問合せ句には、次のように、price
列のみの式が含まれています。
SELECT FROM auction WHERE CATSEARCH(title, 'camera', 'price < 200')> 0; SELECT FROM auction WHERE CATSEARCH(title, 'camera', 'price = 150')> 0; SELECT FROM auction WHERE CATSEARCH(title, 'camera', 'order by price')> 0;
これらの問合せはサブ索引Bを使用して処理できます。ただし、効率を考えてprice
にのみ索引(サブ索引A)を作成することもできます。
begin ctx_ddl.add_index('auction_iset','price'); /* sub-index A */ end;
構造化問合せ句カテゴリB
構造化問合せ句には、price
についての等式にbid_close
でのソートの条件が付与されたもの、およびprice
とbid_close
の両方で(この順に)ソートの条件が付与されたものが含まれます。
SELECT FROM auction WHERE CATSEARCH( title, 'camera','price = 100 ORDER BY bid_close')> 0; SELECT FROM auction WHERE CATSEARCH( title, 'camera','order by price, bid_close')> 0;
これらの問合せは、次のように定義したサブ索引で満たすことができます。
begin ctx_ddl.add_index('auction_iset','price, bid_close'); /* sub-index B */ end;
結合されたBツリー索引と同様に、CTX_DDL.ADD_INDEX
を使用して指定する列の順序は、特定の問合せを満たすために使用される索引スキャンの効率性および実行可能性に影響します。たとえば、2つの構造化列p
とq
にBツリー索引が'p,q'
として指定されている場合、Oracle Textでは、この索引をスキャンして'ORDER
BY q,p'
をソートできません。
4.6.4 CTXCAT索引の作成
この例では、前述の例を結合し、2つのサブ索引を持つ索引セット・プリファレンスを作成します。
begin ctx_ddl.create_index_set('auction_iset'); ctx_ddl.add_index('auction_iset','price'); /* sub-index A */ ctx_ddl.add_index('auction_iset','price, bid_close'); /* sub-index B */ end;
図4-1は、サブ索引AおよびBをAUCTION表から作成する方法を示しています。各サブ索引はそれぞれテキスト列と名前付き構造化列のBツリー索引です。たとえば、サブ索引Aは、title
列とbid_close
列の索引です。
結合されたカタログ索引は、CREATE
INDEX
文を使用して次のように作成します。
CREATE INDEX auction_titlex ON AUCTION(title) INDEXTYPE IS CTXSYS.CTXCAT PARAMETERS ('index set auction_iset') ;
4.7 CTXRULE索引の作成
ドキュメント分類アプリケーションを作成するには、表または問合せにCTXRULE
索引を使用します。着信ドキュメントのストリームがコンテンツで分類されると、問合せによりカテゴリが定義されます。単一ドキュメントの分類には、MATCHES
演算子を使用できます。
CTXRULE
索引および単純なドキュメント分類アプリケーションを作成するには、次の手順に従います。
-
問合せの表を作成します。
カテゴリ名および問合せテキストを保持する
myqueries
表を作成し、この表に分類と各分類を定義する問合せを移入します。CREATE TABLE myqueries ( queryid NUMBER PRIMARY KEY, category VARCHAR2(30), query VARCHAR2(2000) );
たとえば、主題US Politics、MusicおよびSoccerの分類を考えてみます。
INSERT INTO myqueries VALUES(1, 'US Politics', 'democrat or republican'); INSERT INTO myqueries VALUES(2, 'Music', 'ABOUT(music)'); INSERT INTO myqueries VALUES(3, 'Soccer', 'ABOUT(soccer)');
ヒント:
ルール(または問合せ)の表の生成には、
CTX_CLS.TRAIN
プロシージャも使用できます。このプロシージャは入力としてドキュメント・トレーニング・セットを取ります。 -
CTXRULE
索引を作成します。CREATE INDEX
文を使用してCTXRULE
索引を作成し、必要に応じてレクサー、記憶域、セクション・グループおよびワードリストの各パラメータを指定します。CREATE INDEX myruleindex ON myqueries(query) INDEXTYPE IS CTXRULE PARAMETERS ('lexer lexer_pref storage storage_pref section group section_pref wordlist wordlist_pref');
-
ドキュメントを分類します。
MATCHES
演算子を使用してドキュメントを分類します。着信ドキュメントは表
news
に格納されるとします。CREATE TABLE news ( newsid NUMBER, author VARCHAR2(30), source VARCHAR2(30), article CLOB);
必要に応じて、
MATCHES
で「BEFORE INSERT」トリガーを作成して、各ドキュメントをそれぞれの分類に基づいて別の表news_route
にルーティングします。BEGIN -- find matching queries FOR c1 IN (select category from myqueries where MATCHES(query, :new.article)>0) LOOP INSERT INTO news_route(newsid, category) VALUES (:new.newsid, c1.category); END LOOP; END;
関連項目:
-
ドキュメントの分類および
CTXRULE
索引の詳細は、「Oracle Textでのドキュメントの分類」を参照してください