11 XML問合せの結果セット・インタフェースの使用
11.1 XML問合せの結果セット・インタフェースの概要
XML問合せの結果セット・インタフェース(RSI)は、XMLの問合せを実行し、XMLとして結果を戻すことができるため、SELECT
セマンティクス内で有効なSQL層および要件が回避されます。結果セット・インタフェースは、単純なテキスト問合せとXML結果セット記述子を使用し、その結果セット記述子に応じてXMLでヒットリストが戻されます。XML問合せの結果セット・インタフェースは、グループ化およびカウントにSDATA
セクションを使用します。
アプリケーション内の検索結果のページは、最初のいくつかのドキュメントのメタデータ、合計ヒット数、ワード当たりのヒット数など多くの異種要素で構成されます。追加のコールのたびに、問合せを再解析して索引メタデータを検索するための時間がかかります。また、SQLでは、反復問合せ絞込みといった一部の検索操作が難しくなります。SQL文を構成して目的の結果を達成することが可能であっても、通常はこのようなSQLは次善の選択となります。
XML問合せ結果セット・インタフェースは、検索結果のページに必要な様々な種類のデータを同時に作成でき、オーバーヘッドを共有することでパフォーマンスを向上させます。結果セット・インタフェースは、SQLでは表現しにくいデータ・ビューも返すことができます。
11.2 XML問合せの結果セット・インタフェースの使用
CTX_QUERY.RESULT_SET()
およびCTX_QUERY.RESULT_SET_CLOB_QUERY()
APIを使用すると、CONTAINS()
問合せを何度も実行して同じ結果を得るのではなく、単一の問合せで問合せ結果を取得できます。2つのAPIは、一方がVARCHAR2
問合せパラメータを使用し、もう一方がCLOB
問合せを使用してより長い問合せに対応できる点を除き同じです。
たとえば、検索結果ページを表示するには、次の情報を最初に取得する必要があります。
-
日時および関連性でソートされた上位20個のヒット・リスト
-
指定されたテキスト問合せのヒットの総数
-
公開日でグループ化した件数
-
作成者でグループ化した件数
検索するドキュメントを格納する次の表定義を前提とします。
create table docs ( docid number, author varchar2(30), pubdate date, title varchar2(60), doc clob);
次のOracle Text索引の定義を前提とします。
create index docidx on docs(doc) indextype is ctxsys.context filter by author, pubdate, title order by pubdate;
これらの定義を使用する場合、4つのSQL文を発行することによって、検索結果ページを表示するための4つの情報を取得できます。
-- Get top 20 hits sorted by date and relevancy select * from (select /*+ first_rows */ rowid, title, author, pubdate from docs where contains(doc, 'oracle',1)>0 order by pubdate desc, score(1) desc) where rownum < 21; -- Get total number of hits for the given Text query select count(*) from docs where contains(doc, 'oracle',1)>0; -- Get counts group by publication date select pubdate, count(*) from docs where contains(doc, 'oracle',1)>0 group by pubdate; -- Get counts group by author select author, count(*) from docs where contains(doc, 'oracle',1)>0 group by author;
表示されているとおり、同じ問合せを4回実行しているため、別々のSQL文を使用するとリソース集中型の問合せになります。ただし、CTX_QUERY.RESULT_SET()
を使用すると、単一のOracle Textの問合せにこのすべての情報を入力できます。
declare rs clob; begin dbms_lob.createtemporary(rs, true, dbms_lob.session); ctx_query.result_set('docidx', 'oracle text performance tuning', ' <ctx_result_set_descriptor> <count/> <hitlist start_hit_num="1" end_hit_num="20" order="pubDate desc, score desc"> <score/> <rowid/> <sdata name="title"/> <sdata name="author"/> <sdata name="pubDate"/> </hitlist> <group sdata="pubDate"> <count/> </group> <group sdata="author"> <count/> </group> </ctx_result_set_descriptor> ', rs); -- Put in your code here to process the Output Result Set XML dbms_lob.freetemporary(rs); exception when others then dbms_lob.freetemporary(rs); raise; end; /
結果セットの出力は、検索結果ページの作成に必要なすべての情報を含むXMLになります。
<ctx_result_set> <hitlist> <hit> <score>90</score> <rowid>AAAPoEAABAAAMWsAAC</rowid> <sdata name="TITLE"> Article 8 </sdata> <sdata name="AUTHOR">John</sdata> <sdata name="PUBDATE">2001-01-03 00:00:00</sdata> </hit> <hit> <score>86</score> <rowid>AAAPoEAABAAAMWsAAG</rowid> <sdata name="TITLE"> Article 20 </sdata> <sdata name="AUTHOR">John</sdata> <sdata name="PUBDATE">2001-01-03 00:00:00</sdata> </hit> <hit> <score>78</score> <rowid>AAAPoEAABAAAMWsAAK</rowid> <sdata name="TITLE"> Article 17 </sdata> <sdata name="AUTHOR">John</sdata> <sdata name="PUBDATE">2001-01-03 00:00:00</sdata> </hit> <hit> <score>77</score> <rowid>AAAPoEAABAAAMWsAAO</rowid> <sdata name="TITLE"> Article 37 </sdata> <sdata name="AUTHOR">John</sdata> <sdata name="PUBDATE">2001-01-03 00:00:00</sdata> </hit> ... <hit> <score>72</score> <rowid>AAAPoEAABAAAMWsAAS</rowid> <sdata name="TITLE"> Article 56 </sdata> <sdata name="AUTHOR">John</sdata> <sdata name="PUBDATE">2001-01-03 00:00:00</sdata> </hit> </hitlist> <count>100</count> <groups sdata="PUBDATE"> <group value="2001-01-01 00:00:00"><count>25</count></group> <group value="2001-01-02 00:00:00"><count>50</count></group> <group value="2001-01-03 00:00:00"><count>25</count></group> </groups> <groups sdata="AUTHOR"> <group value="John"><count>50</count></group> <group value="Mike"><count>25</count></group> <group value="Steve"><count>25</count></group> </groups> </ctx_result_set>
関連項目:
構文の詳細とCTX_QUERY.RESULT_SET
の詳細は、『Oracle Textリファレンス』を参照してください。
11.3 Oracle TextによるXMLのみのアプリケーションの作成
CONTAINS
句を含むSQL SELECT
文を使用してアプリケーションを作成することが一般的ですが、これは必ずしも作業の最も効率的な方法ではありません。代替方法は、XMLベースの結果セット・インタフェースを使用することです。これを実行する利点は、問合せのすべての結果をフェッチしなくても、サマリー情報(ヒットの総数など)を簡単に取得できることです。
結果セット・インタフェースを使用するには、結果セット記述子(RSD)を指定します。これによって、戻される情報を宣言します。戻される情報は、次の中から選択できます。
-
問合せ結果の合計数
-
ヒットリスト
-
SDATA
フィールドのサマリー情報
次に、ヒットリストは反復要素で構成され、そのそれぞれに次の情報が含まれます。
-
ヒットのROWID
-
ヒットのSDATAフィールド
関連項目:
11.4 結果セット記述子の例
この項の例では、結果セット記述子(RSD)の使用方法を示します。次の例は、上位10個のヒットリスト(スコア順で並替え)と、結果の合計数をリクエストします。
<ctx_result_set_descriptor> <hitlist start_hit_num="1" end_hit_num="10" order="SCORE DESC"> <rowid /> <sdata name="title" /> <sdata name="author" /> <sdata name="articledate" /> <snippet radius="20" max_length="160" starttag="<b>" endtag="</b>" /> </hitlist> <count /> </ctx_result_set_descriptor>
ヒットごとに、rowid
(必要な場合、行の詳細をフェッチするために使用できる)、SDATA
フィールドまたはtitle
、author
およびarticledate
列の内容およびスニペット(キーワードがハイライト表示される簡単な要約、この場合は<b>
...</b>
)をリクエストしています。
11.5 Oracle Textを使用したコロケートの識別
コロケートはドキュメント内で頻繁に共起する単語のグループです。コロケートは、指定されたキーワードに関連するドキュメント内の他のキーワードや概念の簡単な概要を示します。問合せでこれらの他のキーワードを使用してより関連性のある結果を取得できます。
検索問合せに基づいてコロケートを識別します。問合せから返されるドキュメントごとに、検索キーワードに関連するテキストのスニペットが自動的に抽出されます。次に、これらのスニペットの語が統計メジャーを使用して問合せキーワードに関連付けられ、ドキュメント・セット全体における抽出語の発生頻度に応じて、返された各共起語にスコアが割り当てられます。
結果セット・インタフェースはコロケートの識別に使用されます。問合せで返される必要のある共起語の数を指定できます。また、普通名詞のコロケートを指定するか、独自性を強調するコロケートを識別するか指定することもできます。指定された検索キーワードのシノニムも返すことができます。
注意:
コロケートは基本レクサーでのみサポートされます。
コロケートを識別するには:
- 問合せ対象のドキュメント・セットを含む表を作成します。
- ドキュメント・セット表にOracle Text索引を作成します。
- XML問合せの結果セット・インタフェース(RSI)を使用してコロケートを識別する問合せを定義および入力します。必要な属性を持つ
collocates
要素を含めます。
例11-1 ドキュメント・セット内のコロケートの識別
この例で、データ・セット内のドキュメントの問合せに使用されているキーワードは"Nobel"です。Oracle Textは、ドキュメント・セット内のこのキーワードの出現を検索します。結果セットに加えて、コロケートを使用して"Nobel"で共起する5つの共通語を検索します。生成されるコロケートの数は、max_words
属性で識別されます。共通語をコロケート用に識別する必要があることを指定するために、use_tscore
属性がtrueに設定されます。コロケートを識別するためにキーワードの各側で選択する単語の数は10個です。
次に、コロケートの判別に使用される入力結果セット・インタフェース記述子を示します。
declare
rsd varchar2(32767);
begin
ctx_query.result_set('tdrbnbsan01idx', 'nobel',
<ctx_result_set_descriptor>
<collocates radius = "10" max_words="5" use_tscore="TRUE"/>
</ctx_result_set_descriptor>',
:rs);
end;
/
上記問合せの出力結果セットは次のとおりです。
<ctx_result_set>
<collocates>
<collocation>
<word>PRIZE</word>
<score>82</score>
</collocation>
<collocation>
<word>LAUREATE</word>
<score>70</score>
</collocation>
<collocation>
<word>NOBELPRIZE</word>
<score>44</score>
</collocation>
<collocation>
<word>AWARD</word>
<score>42</score>
</collocation>
<collocation>
<word>ORG</word>
<score>41</score>
</collocation
</collocates>
</ctx_result_set>
"Nobel"の上位5つの共通コロケートは上から順に、Prize、Laureate、Nobelprize、award、およびorgです。各語には、発生頻度を示すスコアが割り当てられます。コロケートは、hitlist
要素が返された後常に返されます。
同じ例でuse_tscore
をFALSE
に設定すると、共通性の少ない(一意の)単語が識別されます。出力結果セットは次のようになります。
<ctx_result_set>
<collocates>
<collocation>
<word>MOLA</word>
<score>110</score>
</collocation>
<collocation>
<word>BISMARCK</word>
<score>89</score>
</collocation>
<collocation>
<word>COLONNA</word>
<score>67</score>
</collocation>
<collocation>
<word>LYNEN</word>
<score>55</score>
</collocation>
<collocation>
<word>TIMBERGEN</word>
<score>25</score>
</collocation>
</collocates>
</ctx_result_set>
関連項目:
コロケートで使用する属性の詳細は、『Oracle Textリファレンス』を参照してください。