11 Oracle Textでのドキュメント・セクションの検索
テキスト問合せアプリケーションでドキュメントのセクションを使用できます。
この章のトピックは、次のとおりです:
11.1 Oracle Textでのドキュメントのセクション検索について
セクション検索を使用すると、テキスト問合せをドキュメント内のテキストのブロックに絞り込むことができます。セクション検索は、HTMLやXMLのドキュメントのように、ドキュメントに内部構造がある場合に有効です。
また、テキストを文レベルと段落レベルで検索できます。
この項には、次の項目が含まれます。
11.1.1 Oracle Textでのセクション検索の使用可能化
ドキュメント・コレクションのセクション検索を使用可能にするステップは、次のとおりです。
11.1.1.1 セクション・グループの作成
セクション検索を有効にするには、セクション・グループを定義します。システム定義のセクション・グループのいずれかを使用して、セクション・グループのインスタンスを作成します。ドキュメント・コレクションに適したセクション・グループを選択します。
セクション・グループを使用して、所有しているドキュメント・セットのタイプを指定し、タグ構造を明示的に示します。たとえば、HTMLタグ付きドキュメントを索引付けするには、HTML_SECTION_GROUP
を使用します。同様に、XMLタグ付きドキュメントを索引付けするには、XML_SECTION_GROUP
を使用します。
表11-1は、各種のセクション・グループを示しています。
表11-1 セクション・グループのタイプ
セクション・グループ・プリファレンス | 説明 |
---|---|
|
これはデフォルトです。どのセクションも定義しないか、または |
|
このグループ・タイプを使用して、開始および終了タグが 注意: このグループ・タイプでは、対になっていないカッコ、コメント・タグおよび属性などの入力はサポートされません。これらを入力するには、 |
|
このグループ・タイプを使用して、HTMLドキュメントを索引付けし、HTMLドキュメントのセクションを定義します。 |
|
このグループ・タイプを使用して、XMLドキュメントを索引付けし、XMLドキュメントのセクションを定義します。 |
|
このグループ・タイプを使用して、XMLドキュメントの開始タグ/終了タグに対して自動的にゾーン・セクションを作成します。XMLと同じく、XMLタグから導出されるセクション名では大/小文字が区別されます。 属性セクションは、属性を持つXMLタグに対して自動的に作成されます。属性セクションは、tag@attributeという形式でネーミングされます。 停止セクション、空のタグ、処理命令およびコメントは、索引付けされません。 自動セクション・グループには次の制限事項が適用されます。
|
|
このグループ・タイプを使用して、XMLドキュメントを索引付けします。このプリファレンスは、 相違点は、 |
|
このグループを使用して、RFC 1036に従ったニュース・グループ形式のドキュメントのセクションを定義します。 |
注意:
HTML
、XML
、AUTO
およびPATH
セクショナに送られるドキュメントは、\s*<
で始まる必要があります。\s*
は、0文字以上の空白文字を表します。それ以外のドキュメントはプレーンテキスト・ドキュメントとして処理され、いずれのセクションも認識されません。
CTX_DDL
パッケージを使用してセクション・グループを作成し、セクション・グループの構成要素としてセクションを定義します。たとえば、HTMLドキュメントを索引付けするには、HTML_SECTION_GROUP
を使用してセクション・グループを作成します。
begin ctx_ddl.create_section_group('htmgroup', 'HTML_SECTION_GROUP'); end;
注意:
Oracle Database 18c以降、Oracle TextのNEWS_SECTION_GROUP
の使用は非推奨になりました。かわりに外部処理を使用します。USENET投稿に索引を付ける場合、Oracle Text内でBASIC_SECTION_GROUP
またはHTML_SECTION_GROUP
を使用するように投稿を前処理します。USENETは、商用ではあまり使用されません。
11.1.1.2 セクションの定義
セクションは、セクション・グループの構成要素として定義します。次の例では、HTML <H1>
タグ内の全テキストに対してheadingというゾーン・セクションを定義します。
begin ctx_ddl.create_section_group('htmgroup', 'HTML_SECTION_GROUP'); ctx_ddl.add_zone_section('htmgroup', 'heading', 'H1'); end;
注意:
AUTO_SECTION_GROUP
またはPATH_SECTION_GROUP
を使用して、XMLドキュメント・コレクションを索引付けする場合は、セクションを明示的に定義する必要はありません。索引付け中にセクションが定義されます。
関連項目:
-
セクションの詳細は、「Oracle Textのセクション・タイプ」を参照してください
-
XMLセクション検索の詳細は、「Oracle Textを使用したXMLのセクション検索」を参照してください
11.1.1.3 ドキュメントの索引付け
ドキュメントの索引付け時に、セクション・グループをCREATE
INDEXのPARAMETERS句に指定します。
create index myindex on docs(htmlfile) indextype is ctxsys.context parameters('filter ctxsys.null_filter section group htmgroup');
11.1.1.5 INPATHおよびHASPATH演算子によるパスの検索
PATH_SECTION_GROUP
を使用した場合は、自動的にXMLセクションが作成されます。WITHIN
演算子を使用して問合せを入力できる他、INPATH
演算子とHASPATH
演算子を使用してパス検索を入力できます。
関連項目:
-
これらの演算子の使用方法は、「Oracle Textを使用したXMLのセクション検索」を参照してください
11.1.1.6 SDATAセクションを検索可能にする
SDATA
セクションを検索可能にし、$Sdatatype
表を作成するには、CTX_DDL.SET_SECTION_ATTRIBUTE
APIを使用します。
作成される表は、次のとおりです。
-
$SN
–NUMBER
-
$SD
–DATE
-
$SV
–VARCHAR2
,CHAR
-
$SR
–RAW
-
$SBD
–BINARY DOUBLE
-
$SBF
–BINARY FLOAT
-
$ST
–TIMESTAMP
-
$STZ
–TIMESTAMP WITH TIMEZONE
SDATA
セクションの$SV
表を作成し、そのセクションで効率的な検索を可能にします。ctx_ddl.add_sdata_section('sec_grp', 'sdata_sec', 'mytag', 'varchar');
ctx_ddl.set_section_attribute('sec_grp', 'sdata_sec', 'optimized_for', 'search');
この属性のデフォルト値はFALSEです。
11.1.2 Oracle Textのセクション・タイプ
セクション・タイプはすべて、ドキュメント内のテキストのブロックです。ただし、セクションを区切る方法や索引内での記録方法にそれぞれ相違があります。セクションは、次のタイプのいずれかです。
表11-2に、各種セクション・グループとともに使用されるセクション・タイプを示します。
表11-2 セクション・タイプおよびセクション・グループ
セクション・グループ | ZONE | FIELD | STOP | MDATA | NDATA | SDATA | ATTRIBUTE | SPECIAL |
---|---|---|---|---|---|---|---|---|
NULL |
NO |
NO |
NO |
NO |
NO |
NO |
NO |
YES |
BASIC |
YES |
YES |
NO |
YES |
YES |
YES |
NO |
YES |
HTML |
YES |
YES |
NO |
YES |
YES |
YES |
NO |
YES |
XML |
YES |
YES |
NO |
YES |
YES |
YES |
YES |
YES |
NEWS |
YES |
YES |
NO |
YES |
YES |
YES |
NO |
YES |
AUTO |
NO |
NO |
YES |
NO |
NO |
NO |
NO |
NO |
PATH |
NO |
NO |
NO |
NO |
NO |
NO |
NO |
NO |
11.1.2.1 ゾーン・セクション
ゾーン・セクションは、ドキュメント内の開始タグと終了タグで区切られたテキストの本体です。開始タグと終了タグの位置は索引内に記録されているため、タグで囲まれたワードはそのセクション内に存在するとみなされます。ゾーン・セクションのインスタンスすべてに開始タグと終了タグが付いている必要があります。
たとえば、<TITLE>
と</TITLE>
の2つのタグに挟まれたテキストは、ゾーン・セクションとして次のように定義します。
<TITLE>Tale of Two Cities</TITLE> It was the best of times...
ゾーン・セクションは、ドキュメント内でネスト、オーバーラップおよび繰返しができます。
ゾーン・セクションの問合せ時に、全セクション内の語句を検索するには、WITHIN
演算子を使用します。Oracle Textにより、定義済のセクション内に問合せ語句を含むドキュメントが戻ります。
ゾーン・セクションは、HTMLおよびXMLドキュメントのセクションの定義に最適です。ゾーン・セクションを定義するには、CTX_DDL
.ADD_ZONE_SECTION.
を使用します
たとえば、次のようにbooktitle
というセクションを定義したとします。
begin ctx_ddl.create_section_group('htmgroup', 'HTML_SECTION_GROUP'); ctx_ddl.add_zone_section('htmgroup', 'booktitle', 'TITLE'); end;
索引付けした後で、booktitle
セクション内の語句 Citiesを含むすべてのドキュメントを次のように検索できます。
'Cities WITHIN booktitle'
(dog and cat) WITHIN booktitleのような複数の問合せ語句の場合は、Oracle Textにより、booktitle
セクションの同じインスタンス内にcatとdogを含むドキュメントが検出されます。
繰返しゾーン・セクション
ゾーン・セクションは繰返しが可能です。出現はそれぞれ別セクションとして処理されます。たとえば、<H1>
がheading
セクションを示す場合は、次のように同じドキュメント内でheadingを繰り返すことができます。
<H1> The Brown Fox </H1> <H1> The Gray Wolf </H1>
これらのゾーン・セクションがHeading
という名前の場合、問合せBrown WITHIN Headingはこのドキュメントを戻します。ただし、(Brown and Gray) WITHIN Headingという問合せはできません。
ゾーン・セクションのオーバーラップ
ゾーン・セクションは互いにオーバーラップできます。たとえば、<B>
と<I>
が2つの異なるゾーン・セクションを示す場合、これらはドキュメント内で次のようにオーバーラップできます。
plain <B> bold <I> bold and italic </B> only italic </I> plain
ネストされたゾーン・セクション
ゾーン・セクションは、次のようにネストできます。
<TD> <TABLE><TD>nested cell</TD></TABLE></TD>
WITHIN
演算子を使用して、セクション内のセクションのテキストを検索するための問合せを記述できます。たとえば、BOOK1、BOOK2
およびAUTHOR
のゾーン・セクションが、ドキュメントdoc1およびdoc2で次のように出現するとします。
doc1:
<book1> <author>Scott Tiger</author> This is a cool book to read.</book1>
doc2:
<book2> <author>Scott Tiger</author> This is a great book to read.</book2>
次のようにネストされた問合せを実行します。これはdoc1のみを戻します。
'(Scott within author) within book1'
11.1.2.2 フィールド・セクション
フィールド・セクションは、ゾーン・セクションと同じように、開始タグと終了タグで区切られたテキストの範囲です。フィールド・セクションはゾーン・セクションより効率的で、リージョンがドキュメントの残りの部分とは別に索引付けされる点でゾーン・セクションと異なります。作成できるフィールド・セクションの数は無制限です。
フィールド・セクションは異なる方法で索引付けされるため、大量のドキュメントが索引付けされている場合は、ゾーン・セクションに比べて問合せパフォーマンスが向上します。
フィールド・セクションは、ニュース・ヘッダーのフィールドなどドキュメントに1回のみ出現するセクションに最適です。また、フィールド・セクションは、ドキュメントの残りの部分で参照できます。
ゾーン・セクションとは異なり、フィールド・セクションには次の制限事項があります。
-
オーバーラップできません。
-
繰り返すことはできません。
-
ネストできません。
Visibleなフィールド・セクションおよびInvisibleなフィールド・セクション
デフォルトでは、フィールド・セクションはドキュメントの残りの部分とは別にサブドキュメントとして索引付けされます。このため、フィールド・セクションは前後のテキストから参照不能であり、WITHIN
句でそのセクション名を明示的に指定することによってのみ問い合せることができます。
フィールド・セクション内のテキストをドキュメント全体の一部として索引付けする場合は、フィールド・セクションを参照可能にできます。参照可能なフィールド・セクション内のテキストは、WITHIN
演算子を使用してもしなくても問い合せることができます。
次の例では、参照不能なフィールド・セクションと参照可能なフィールド・セクションの相違点を示します。このコードは、BASIC_SECTION_GROUP
型のbasicgroup
セクション・グループを定義します。次に、<A>
タグに対してAuthor
というフィールド・セクションをbasicgroup
に作成します。また、参照可能フラグをFALSE
に設定して、参照不能なセクションを作成します。
begin ctx_ddl.create_section_group('basicgroup', 'BASIC_SECTION_GROUP'); ctx_ddl.add_field_section('basicgroup', 'Author', 'A', FALSE); end;
Author
フィールド・セクションは参照不能であるため、Author
セクション内のテキストを検索するには、次のようにWITHIN
演算子を使用する必要があります。
'(Martin Luther King) WITHIN Author'
WITHIN
演算子を使用せずにMartin Luther Kingを問い合せても、フィールド・セクション内のこの語句のインスタンスは戻りません。WITHIN
を指定せずにフィールド・セクション内のテキストを問い合せる場合は、セクション作成時に次のように参照可能フラグをTRUE
に設定する必要があります。
begin ctx_ddl.add_field_section('basicgroup', 'Author', 'A', TRUE); end;
ネストされたフィールド・セクション
フィールド・セクションはネストできません。たとえば、フィールド・セクションを<TITLE>
で始まるように定義し、別のフィールド・セクションを<FOO>
で始まるように定義した場合、この2つのセクションを次のようにネストすることはできません。
<TITLE> dog <FOO> cat </FOO> </TITLE>
ネストされたセクションを使用するには、これらをゾーン・セクションとして定義します。
繰返しフィールド・セクション
繰返しフィールド・セクションは使用できますが、WITHIN
問合せはこれらを1つのセクションとして処理します。次に、ドキュメントの繰返しフィールド・セクションの例を示します。
<TITLE> cat </TITLE> <TITLE> dog </TITLE>
問合せ(dog and cat)within titleは、これらのワードが別のセクション内に存在している場合でも、ドキュメントを検出します。
WITHIN
問合せで繰返しセクションを区別するには、これらをゾーン・セクションとして定義します。
11.1.2.3 停止セクション
自動セクション・グループに停止セクションを追加すると、自動セクション索引付け演算子では、XMLドキュメントの指定されたセクションが無視されます。
注意:
停止セクションを追加すると、索引内にセクション情報が作成されません。ただし、停止セクション内のテキストは常に検索可能です。
ユーザーのドキュメントに多数の下位レベルの情報タグが含まれているときに、停止セクションを追加すると役立ちます。また、停止セクションを追加すると、自動セクション・グループを使用した索引付けのパフォーマンスが向上します。
追加できる停止セクションの数は無制限です。
停止セクションにはセクション名がないため、セクション・ビューに記録されません。
11.1.2.4 MDATAセクション
MDATA
セクションは、ドキュメントに対するユーザー定義済メタデータの参照に使用します。MDATA
セクションによって複合問合せを高速化でき、問合せで戻すことができるMDATA
セクションの数に制限はありません。
テキストの内容およびドキュメント・タイプ(雑誌、新聞、小説など)に応じた問合せをする場合を考えます。テキストの列およびドキュメント・タイプの列を含む索引を作成してから、この形式の複合問合せを実行できます。この場合、Adam Thorpe (小説Ulvertonの著者)という句を含むすべての小説を検索します。
SELECT id FROM documents WHERE doctype = 'novel' AND CONTAINS(text, 'Adam Thorpe')>0;
ただし、通常は、別々の列を使用するよりも、属性(この場合はドキュメント・タイプ)を1つのフィールド・セクションに組み込み、1つのCONTAINS
問合せを使用する方が速くなります。
SELECT id FROM documents WHERE CONTAINS(text, 'Adam Thorpe AND novel WITHIN doctype')>0;
このアプローチには2つのデメリットがあります。
-
属性が更新されるたびに、テキスト・ドキュメント全体を再索引付けする必要があります。その結果、索引の断片化が進み、データ操作言語(DML)処理のレートが遅くなります。
-
フィールド・セクションにより、セクション値がトークン化します。トークン化は、次のように影響を及ぼします。小数点または通貨記号などの、メタデータ内の特殊文字は簡単に検索できない、値の検索が困難(John Smithは検索できるが、John Smith, Jr.は検索できないなど)、マルチ・ワードの値を句で問い合せるため、単一のトークン検索よりも遅くなる、マルチ・ワードの値がブラウズ・ワードで表示されないため、作成者のブラウズや主題のブラウズが不可能になる、などです。
そのため、フィールド・セクションではなくMDATA
セクションを使用した方が有効です。MDATA
セクションは、フィールド・セクションのように索引付けされますが、メタデータ値を追加し、ドキュメント・テキストを再索引付けせずにドキュメントから削除できます。フィールド・セクションとは異なり、MDATA
値はトークン化されません。また、MDATA
セクションの索引付けは、通常、フィールド・セクションの索引付けよりも使用するディスク・スペースが小さくてすみます。
Oracle Database 12cリリース2 (12.2)以降、MDATA
セクションを、その読取り専用タグの値に応じて更新可能または更新不可にすることができるようになりました。値はFALSE
またはTRUE
に設定できます。
MDATA
セクションをセクション・グループに追加するには、CTX_DDL.ADD_MDATA_SECTION
を使用します。デフォルトでは、読取り専用のMDATA
セクションの値はFALSE
です。これは、このMDATA
セクションに対してCTX_DDL.ADD_MDATA()
およびCTX_DDL.REMOVE_MDATA()
をコールできることを意味します。そうしない場合は、TRUE
に設定できます。FALSE
に設定すると、MDATA
セクションに対する問合せは、そのMDATA
セクションの削除された値を追跡するために索引表でカーソルをオープンする必要があるため、効率よく実行できません。この例では、AUTHOR
というMDATA
セクションを追加し、これに「Soseki Natsume」(小説「Kokoro」の作者)という値を指定します。
ctx_ddl.create.section.group('htmgroup', 'HTML_SECTION_GROUP'); ctx_ddl.add_mdata_section('htmgroup', 'author', 'Soseki Natsume');
MDATA
値を変更するにはCTX_DDL.ADD_MDATA
を使用し、削除するにはCTX_DDL.REMOVE_MDATA
を使用します。また、MDATA
セクションには複数の値を指定できます。索引の所有者のみがCTX_DDL.ADD_MDATA
およびCTX_DDL.REMOVE_MDATA.
をコールできます
CTX_DDL.ADD_MDATA
およびCTX_DDL.REMOVE_MDATA
は、両方ともCTXCAT
索引およびCTXRULE
索引に対してサポートされていません。
MDATA
値はレクサーを介して渡されません。かわりに、すべての値は次のように簡単に正規化されます。
-
値に隣接する空白は削除されます。
-
値は255バイトに切り捨てられます。
-
値は単一の値として索引付けされます。値が複数のワードから構成されていても、分割されません。
-
大/小文字の区別は保持されます。ドキュメントが動的に生成される場合は、
MDATA
値を大文字化し、大文字のみが検索されることを確認することで、大/小文字区別を実装できます。
ドキュメントにMDATA
メタデータを追加した後、CONTAINS
問合せ演算子を使用して、メタデータを問い合せることができます。
SELECT id FROM documents WHERE CONTAINS(text, 'Tokyo and MDATA(author, Soseki Natsume)')>0;
AUTHOR
タグに正確な値Soseki Natsumeがある場合(単純なトークン化後)のみ、この問合せは成功します。SosekiまたはNatsume Sosekiで行は返されません。
以下に、MDATA
の考慮事項を示します。
-
MDATA
値はハイライト表示されず、CTX_DOC.TOKENS
の出力には含められず、FILTER PLAINTEXT
を有効にしているときも含められません。 -
MDATA
セクションは、セクション・グループ内で一意にする必要があります。たとえば、同じセクション・グループでMDATA
セクション、ゾーン・セクションまたはフィールド・セクションの名前としてFOO
を使用しないでください。 -
フィールド・セクションと同様に、
MDATA
セクションはオーバーラップまたはネストできません。MDATA
セクションは、最初に発生したタグにより、暗黙的にクローズされます。この例の内容は次のとおりです。<AUTHOR>Dickens <B>Shelley</B> Keats</AUTHOR>
<B>
タグにより、AUTHOR
MDATA
セクションがクローズされます。その結果、このドキュメントには「Shelley」や「Keats」ではなく、「Dickens」というAUTHOR
が含まれます。 -
競合状態を未然に防ぐため、
ADD_MDATA
およびREMOVE_MDATA
をそれぞれコールして、すべての値とセクションの索引のROWIDに対する他のコールをロックします。ただし、ADD_MDATA
およびREMOVE_MDATA
はコミットを行わないため、両方をコールするとアプリケーションでデッドロックが発生する可能性があります。デッドロックを回避するのはアプリケーションの役割です。
関連項目:
-
『Oracle Textリファレンス』の
ALTER INDEX
に関する説明 -
『Oracle Textリファレンス』の
ADD_MDATA_SECTION
に関する説明 -
MDATA
演算子の詳細は、『Oracle Textリファレンス』のCONTAINS
問合せ演算子」を参照してください。 -
MDATA
セクションの追加および削除の詳細は、『Oracle Textリファレンス』の「CTX_DDL
パッケージ」を参照してください。
11.1.2.5 NDATAセクション
NDATA
セクションをBASIC_SECTION_GROUP
、HTML_SECTION_GROUP
またはXML_SECTION_GROUP
セクション・グループ・タイプに追加して、名前検索用に索引付けするデータを含むフィールドを排他的に指定できます。
ユーザーは、使用可能な2つのデータストア(MULTI_COLUMN_DATASTORE
またはUSER_DATASTORE
)を使用して、名前データを含むテキスト・ドキュメントを合成できます。次の例では、MULTI_COLUMN_DATASTORE
を使用して、索引付け用の名前データが含まれている関連する列を取得しています。
create table people(firstname varchar2(80), surname varchar2(80)); insert into people values('John', 'Smith'); commit; begin ctx_ddl.create_preference('nameds', 'MULTI_COLUMN_DATASTORE'); ctx_ddl.set_attribute('nameds', 'columns', 'firstname,surname'); end; /
この例では、索引付けに使用する次の仮想テキストを作成しています。
<FIRSTNAME> John </FIRSTNAME> <SURNAME> Smith </SURNAME>
これで、FIRSTNAME
およびSURNAME
セクションにNDATA
セクションを作成できます。
begin ctx_ddl.create_section_group('namegroup', 'BASIC_SECTION_GROUP'); ctx_ddl.add_ndata_section('namegroup', 'FIRSTNAME', 'FIRSTNAME'); ctx_ddl.add_ndata_section('namegroup', 'SURNAME', 'SURNAME'); end; /
次に、以前に作成したデータストア・プリファレンスとセクション・グループ・プリファレンスを使用して、索引を作成します。
create index peopleidx on people(firstname) indextype is ctxsys.context parameters('section group namegroup datastore nameds');
NDATA
セクションでは、シングルバイト・データとマルチバイト・データの両方がサポートされていますが、文字および語句に関する制約があります。索引付けされるNDATA
セクション・データには、次の制約があります。
-
1文字の空白で区切られた語句の文字数: 511
-
空白で区切られた語句の数: 255
-
空白を含めた文字の総数: 511
11.1.2.6 SDATAセクション
SDATA
セクションの値は、他のセクションなどのドキュメント・テキストから抽出されますが、構造化データとして索引付けされ、SDATA
とも呼ばれます。SDATA
セクションは、投影、範囲検索、順序付けなどの操作をサポートしています。また、SDATA
セクションでは、セクション・データ(埋込みタグなど)およびディテール表のSDATA
索引付けやファンクション起動ができます。1つのSQL文でテキスト検索と構造化検索の様々な組合せを実行できます。
SDATA
演算子は、SDATA
以外の子孫もあるAND
演算子の子としてのみ使用してください。SDATA
演算子は、二次的な(確認または非駆動)基準として使用することが意図されています。たとえば、「評価が> 4のドキュメントの検索」ではなく、「DOGという語句が含まれており、価格が> 5でもあるドキュメントの検索」に使用します。
SDATA
セクションをセクション・グループに追加するには、CTX_DDL.ADD_SDATA_SECTION
を使用します。既存のSDATA
セクションの値を更新するには、CTX_DDL.UPDATE_SDATA
を使用します。SDATA
セクション内で問い合せる場合は、CONTAINS
演算子を使用する必要があります。次の例では、items
という表を作成し、my_sec_group
というSDATA
セクションを追加して、セクション内のSDATA
を問い合せます。
SDATA
セクションの作成後に、CTX_DDL.SET_SECTION_ATTRIBUTE
を使用すればSDATA
セクションの属性をさらに変更できます。
items
表を作成します。
CREATE TABLE items (id NUMBER PRIMARY KEY, doc VARCHAR2(4000)); INSERT INTO items VALUES (1, '<description> Honda Pilot </description> <category> Cars & Trucks </category> <price> 27000 </price>'); INSERT INTO items VALUES (2, '<description> Toyota Sequoia </description> <category> Cars & Trucks </category> <price> 35000 </price>'); INSERT INTO items VALUES (3, '<description> Toyota Land Cruiser </description> <category> Cars & Trucks </category> <price> 45000 </price>'); INSERT INTO items VALUES (4, '<description> Palm Pilot </description> <category> Electronics </category> <price> 5 </price>'); INSERT INTO items VALUES (5, '<description> Toyota Land Cruiser Grill </description> <category> Parts & Accessories </category> <price> 100 </price>'); COMMIT;
my_sec_group
SDATA
セクションを追加します。
BEGIN CTX_DDL.CREATE_SECTION_GROUP('my_sec_group', 'BASIC_SECTION_GROUP'); CTX_DDL.ADD_SDATA_SECTION('my_sec_group', 'category', 'category', 'VARCHAR2'); CTX_DDL.ADD_SDATA_SECTION('my_sec_group', 'price', 'price', 'NUMBER'); END;
CONTEXT
索引を作成します。
CREATE INDEX items$doc ON items(doc) INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS('SECTION GROUP my_sec_group');
問合せを実行します。
SELECT id, doc FROM items WHERE contains(doc, 'Toyota AND SDATA(category = ''Cars & Trucks'') AND SDATA(price <= 40000 )') > 0;
結果を返します。
ID DOC ---- ---------------------------------------------------------------------- 2 <description> Toyota Sequoia </description> <category> Cars & Trucks </category> <price> 35000 </price>
ROWIDが1であるドキュメントについて考えてみます。この例では、price
SDATA
セクションの値を新しい値30000に更新しています。
BEGIN SELECT ROWID INTO rowid_to_update FROM items WHERE id=1; CTX_DDL.UPDATE_SDATA('items$doc', 'price', SYS.ANYDATA.CONVERTVARCHAR2('30000'), rowid_to_update); END;
この問合せを実行すると、Honda Pilot
の価格が27000から30000に変更されます。
注意:
-
SDATA
セクションを既存の索引に追加することもできます。ALTER INDEX PARAMETERS
文のADD SDATA SECTION
パラメータを使用します。詳細は、『Oracle Textリファレンス』のALTER INDEXセクションに関する項を参照してください。 -
SDATA
セクションを追加する前に索引付けされたドキュメントには、この新しいプリファレンスは反映されません。この場合は索引を再構築してください。
関連項目:
-
SDATA
演算子の詳細は、『Oracle Textリファレンス』のCONTAINS
の問合せに関する項を参照してください -
SDATA
セクションの追加および更新と、ADD_SDATA_SECTION
、SET_SECTION_ATTRIBUTE
およびUPDATE_SDATA
プロシージャを使用してその属性を変更する方法の詳細は、『Oracle Textリファレンス』のCTX_DDL
パッケージに関する項を参照
記憶域
optimized_for
search SDATA
セクションでは、CTX_DDL.SET_ATTRIBUTE
を使用して、$Sdatatype
表とこれらの表の索引の記憶域プリファレンスを指定できます。
デフォルトでは、ラージ・オブジェクト(LOB)キャッシュは$S*
表に対してはオンになり、$S*
索引に対してはオフになります。これらの属性はSDATA
セクションでのみ有効です。
問合せ演算子
Optimized_for search SDATA
では、次の問合せ演算子がサポートされます。
-
=
-
<>
-
範囲内
-
範囲外
-
<=
-
<
-
>=
-
>
-
NULLである
-
NULLでない
-
類似
-
非類似
11.1.2.8 特殊セクション
特殊セクションは、タグで認識されるのではありません。現在、特殊セクションとしては文および段落のみがサポートされ、これらを使用すると、文または段落内でワードの組合せを検索できます。
文および段落の境界は、レクサーが判断します。たとえば、BASIC_LEXER
は、文および段落のセクション境界を次のように認識します。
表11-3 BASIC_LEXERの文および段落セクション境界
特殊セクション | 境界 |
---|---|
SENTENCE |
|
PARAGRAPH |
|
レクサーが境界を認識できない場合、文または段落のセクションには索引が付けられません。
特殊セクションを追加するには、CTX_DDL
.ADD_SPECIAL_SECTION
プロシージャを使用します。たとえば、次のコードではHTMLドキュメントの文内を検索できます。
begin ctx_ddl.create_section_group('htmgroup', 'HTML_SECTION_GROUP'); ctx_ddl.add_special_section('htmgroup', 'SENTENCE'); end;
ゾーンおよび文の検索を有効にするには、ゾーン・セクションをグループに追加します。次の例では、Headline
ゾーン・セクションをhtmgroup
セクション・グループに追加しています。
begin ctx_ddl.create_section_group('htmgroup', 'HTML_SECTION_GROUP'); ctx_ddl.add_special_section('htmgroup', 'SENTENCE'); ctx_ddl.add_zone_section('htmgroup', 'Headline', 'H1'); end;
11.1.3 Oracle Textセクション属性
セクション属性は、フィールド、ゾーン、ハイブリッド、SDATA
など、トークン化されたタイプのOracle Textセクションの設定です。セクション属性を使用すると、ドキュメント・レベルや索引レベルではなくセクション・レベルでより細かく制御することで、問合せパフォーマンスが向上します。
セクション属性を使用して、次のことを指定できます。
-
ドキュメントの特定のセクションに対するレクサー・プリファレンス。このプリファレンスは、部分名検索に便利です。ドキュメントで部分名を含む特定のセクションについては、ドキュメントの他の部分とは異なるレクサー処理が必要なためです。また、レクサー・プリファレンスは、言語マッピングへのセクションがある複数言語のドキュメントの処理にも使用できます。
-
ドキュメントの特定セクションでのみのサブストリング索引。この索引は、索引サイズの削減に効果があります。
-
ドキュメントの特定セクションでのみのプリフィックス・トークン。プリフィックス・トークンにより、前方一致問合せのパフォーマンスが向上しますが、索引サイズは短時間で大きくなります。プリフィックス・トークンを特定セクションのみに指定すれば、特定セクションでの後方一致問合せのパフォーマンスが向上する一方、索引サイズが短時間で増加することがなくなります。
-
ドキュメントの特定セクションのストップリスト。
-
ゾーン・セクションの柔軟性とフィールド・セクションのパフォーマンスをあわせ持つ新しいセクション・タイプ。現在、ゾーン・セクションはフィールド・セクションに比べるとパフォーマンスの点で劣ります。しかし、フィールド・セクションはネストしたセクション検索をサポートしていません。
セクション属性を設定するには、CTX_DDL.SET_SECTION_ATTRIBUTE
プロシージャを使用します。
表11-4に、使用できるセクション属性を示します。
表11-4 セクション属性
セクション属性 | 説明 |
---|---|
|
ドキュメントでテキストを参照可能にするとき、 デフォルトは フィールド・セクション・タイプの場合、visible属性は |
|
SDATAセクションのトークン化を決定するレクサー・プリファレンス名を指定します。デフォルトは レクサー・プリファレンスは、 |
|
セクション固有のプリフィックス索引付けとサブストリング索引付けを有効にするには、セクションのワードリスト・プリファレンス名を指定します。デフォルトは ワードリスト・プリファレンスは、 |
|
セクション固有のストップリストを有効にするには、ストップリスト・プリファレンス名を指定します。デフォルトは ストップリスト・プリファレンスは、 |
次の例は、フィールド・セクションのvisible
属性を有効にします。
begin ctx_ddl.create_section_group(‘fieldgroup', ‘BASIC_SECTION_GROUP'); ctx_ddl.add_field_section(‘fieldgroup', ‘author', ‘AUTHOR'); ctx_ddl.set_section_attribute(‘fieldgroup', ‘author', ‘visible', ‘true'); end;
関連項目:
CTX_DDL.SET_SECTION_ATTRIBUTE
プロシージャの構文は、『Oracle Textリファレンス』を参照してください。
11.2 Oracle Textを使用したHTMLのセクション検索
HTMLには、セクション検索に使用できるタグ付きテキスト形式の内部構造があります。たとえば、<H1>
タグに対してheadings
というセクションを定義し、ドキュメント・セット全体でこれらのタグ内でのみ語句を検索します。
問合せには、WITHIN
演算子を使用します。Oracle Textにより、headings
セクション内に問合せ語句を含むすべてのドキュメントを検出します。たとえば、headings
セクション内にワードoracle
を含むすべてのドキュメントを検索する場合は、次の問合せを入力します。
'oracle within headings'
この項には、次の項目が含まれます。
11.2.1 HTMLのセクションの作成
次のコードは、HTML_SECTION_GROUP
型のhtmgroup
というセクション・グループを定義します。次に、htmgroup
に、<H1>
タグで識別するheading
というゾーン・セクションを作成します。
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('filter ctxsys.null_filter section group htmgroup');
htmgroup
セクション・グループで索引付けした後、次の問合せを発行してheading
セクション内を問い合せることができます。
'Oracle WITHIN heading'
11.2.2 HTMLのMetaタグの検索
HTMLドキュメントの場合は、<META>
タグのNAME/CONTENT
のペアにセクションを作成できます。このとき、検索をCONTENT
内のテキストに制限できます。
次のMETA
タグを持つHTMLドキュメントがあるとします。
<META NAME="author" CONTENT="ken">
META
タグに対してすべてのCONTENT
属性を索引付けるゾーン・セクションを作成します。この場合、METAタグのNAME値
はauthorです。
begin ctx_ddl.create_section_group('htmgroup', 'HTML_SECTION_GROUP'); ctx_ddl.add_zone_section('htmgroup', 'author', 'meta@author'); end
htmgroup
セクション・グループで索引付けした後、次のようにドキュメントを問い合せることができます。
'ken WITHIN author'
11.3 Oracle Textを使用したXMLのセクション検索
HTMLドキュメントと同様、XMLドキュメントにもタグ付きテキストがあるため、これを使用して、セクション検索を行うテキストのブロックを定義できます。セクションの内容を検索するには、WITHIN
演算子またはINPATH
演算子を使用します。
次の各項では、様々なタイプのXML検索について説明します。
11.3.1 自動セクション
XMLドキュメントからセクションを自動的に作成するように索引付け操作を設定するには、AUTO_SECTION_GROUP
セクション・グループを使用します。システムは、XMLタグに対してゾーン・セクションを作成します。属性セクションは、属性を持つタグに対して作成され、tag@attribute
という形式でネーミングされます。
たとえば、次の文はAUTO_SECTION_GROUP
を使用して、XMLファイルを含む列にmyindex索引を作成します。
CREATE INDEX myindex ON xmldocs(xmlfile) INDEXTYPE IS ctxsys.context PARAMETERS ('datastore ctxsys.default_datastore filter ctxsys.null_filter section group ctxsys.auto_section_group' );
11.3.2 属性検索
XML属性テキストは、次のいずれかの方法で検索できます。
-
属性セクションの作成
属性セクションを作成するには
CTX_DDL
.ADD_ATTR_SECTION
を使用し、索引付けするにはXML_SECTION_GROUP
を使用します。索引付けするときにAUTO_SECTION_GROUP
を使用した場合は、属性セクションが自動的に作成されます。属性セクションは、WITHIN
演算子で問い合せることができます。次のように、
TITLE
属性を持つBOOK
タグを定義するXMLファイルがあるとします。<BOOK TITLE="Tale of Two Cities"> It was the best of times. </BOOK>
タイトル属性を属性セクションとして定義するには、次のように
XML_SECTION_GROUP
を作成し、属性セクションを定義します。begin ctx_ddl.create_section_group('myxmlgroup', 'XML_SECTION_GROUP'); ctx_ddl.add_attr_section('myxmlgroup', 'booktitle', 'book@title'); end;
索引付けは、次のように行います。
CREATE INDEX myindex ON xmldocs(xmlfile) INDEXTYPE IS ctxsys.context PARAMETERS ('datastore ctxsys.default_datastore filter ctxsys.null_filter section group myxmlgroup' );
booktitle XML属性セクションを問い合せる手順は、次のとおりです。
'Cities within booktitle'
-
INPATH演算子による属性の検索
PATH_SECTION_GROUP
を使用して索引付けし、INPATH
演算子で属性テキストを問い合せます。
関連項目:
11.3.3 ドキュメント・タイプ別のセクション
異なるドキュメント・タイプに対して宣言された<book>
タグを持つXMLドキュメント・セットの場合、各ドキュメント・タイプに対して個別のbookセクションを作成すると、検索機能を改善できます。次の例では、各ドキュメント・タイプに対してbookセクションを作成する方法を示します。
mydocname1
がXMLドキュメント・タイプ(ルート要素)として、次のように宣言されているとします。
<!DOCTYPE mydocname1 ... [...
mydocname1
の中で、<book>
要素が宣言されています。このタグに対し、タグのドキュメント・タイプを区別するmybooksec1
という名前のセクションを次のように作成できます。
begin
ctx_ddl.create_section_group('myxmlgroup', 'XML_SECTION_GROUP'); ctx_ddl.add_zone_section('myxmlgroup', 'mybooksec1', 'mydocname1(book)');
end;
mydocname2
が別のXMLドキュメント・タイプ(ルート要素)として、次のように宣言されているとします。
<!DOCTYPE mydocname2 ... [...
mydocname2
の中で、<book>
要素が宣言されています。このタグに対し、タグのドキュメント・タイプを区別するmybooksec2
という名前のセクションを次のように作成できます。
begin
ctx_ddl.create_section_group('myxmlgroup', 'XML_SECTION_GROUP'); ctx_ddl.add_zone_section('myxmlgroup', 'mybooksec2', 'mydocname2(book)');
end;
mybooksec1
セクション内で問合せを行うには、WITHIN
を次のように使用します。
'oracle within mybooksec1'
11.3.4 パス・セクション検索
XMLドキュメントには、次のような親子タグの構造を設定できます。
<A> <B> <C> dog </C> </B> </A>
この例のタグCは、タグAの子であるタグBの子です。
Oracle Textでは、PATH_SECTION_GROUP
でパスを検索できます。このセクション・グループを使用すると、問合せ内に直接の親子関係を指定できます。たとえば、要素Bの子である要素Cにある語句dogを含むすべてのドキュメントを検索できます。
PATH_SECTION_GROUP
を使用すると、属性値検索および属性の等価性のテストも実行できます。
この機能に関連する新しい演算子は、次のとおりです。
-
INPATH
-
HASPATH
この項では、次の項目について説明します。
11.3.4.1 PATH_SECTION_GROUPによる索引の作成
パス・セクション検索を使用可能にするには、PATH_SECTION_GROUP
を使用してXMLドキュメント・セットを索引付けします。たとえば、次のようにします。
プリファレンスを作成します。
begin ctx_ddl.create_section_group('xmlpathgroup', 'PATH_SECTION_GROUP'); end;
索引を作成します。
CREATE INDEX myindex ON xmldocs(xmlfile) INDEXTYPE IS ctxsys.context PARAMETERS ('datastore ctxsys.default_datastore filter ctxsys.null_filter section group xmlpathgroup' );
索引を作成するときに、INPATH
演算子とHASPATH
演算子を使用できます。
11.3.4.2 トップレベルのタグ検索
トップレベルのタグ<A>
に、語句dogが含まれているすべてのドキュメントを検索するには、次の問合せを行います。
dog INPATH (/A)
または
dog INPATH(A)
11.3.4.3 任意レベルのタグ検索
任意レベルの<A>
タグに語句dogが含まれているすべてのドキュメントを検索するには、次の問合せを行います。
dog INPATH(//A)
この問合せは、次のドキュメントを検索します。
<A>dog</A>
および
<C><B><A>dog</A></B></C>
11.3.4.4 直接の親子関係の検索
トップレベルの要素Aの直接の子である要素Bに語句dogが含まれているすべてのドキュメントを検索するには、次の問合せを行います。
dog INPATH(A/B)
この問合せは、次のXMLドキュメントを検索します。
<A><B>My dog is friendly.</B></A>
ただし、次の語句は検索しません。
<C><B>My dog is friendly.</B></C>
11.3.4.5 タグ値のテスト
タグの値をテストできます。たとえば、次の問合せ
dog INPATH(A[B="dog"])
は、次のドキュメントを検索します。
<A><B>dog</B></A>
ただし、次のドキュメントは検索しません。
<A><B>My dog is friendly.</B></A>
11.3.4.6 属性検索
属性の内容を検索できます。たとえば、次の問合せ
dog INPATH(//A/@B)
次のドキュメントを検索します。
<C><A B="snoop dog"> </A> </C>
11.3.4.7 属性値のテスト
属性の値をテストできます。たとえば、次の問合せ
California INPATH (//A[@B = "home address"])
次のドキュメントを検索します。
<A B="home address">San Francisco, California, USA</A>
ただし、次の語句は検索しません。
<A B="work address">San Francisco, California, USA</A>
11.3.4.8 パスのテスト
HASPATH
演算子を使用して、パスの存在をテストできます。たとえば、次の問合せ
HASPATH(A/B/C)
は、次のドキュメントを検索して、スコア100を戻します。
<A><B><C>dog</C></B></A>
この問合せでは、dogは参照されません。
11.3.4.9 HASPATHによるセクションの等価性のテスト
HASPATH
演算子を使用すると、セクションの等価性をテストできます。たとえば、次の問合せを考えてみます。
dog INPATH A
次のように検索されます。
<A>dog</A>
さらに、次のドキュメントも検索します。:
<A>dog park</A>
問合せを、語句dogのみに制限し、それ以外の語句を検索しないようにする場合は、HASPATH
演算子によるセクションの等価性のテストを使用できます。たとえば、次のようになります
HASPATH(A="dog")
最初のドキュメントのみを検索し、スコア100を戻します。2番目のドキュメントは検索しません。