15 XML問合せの結果セット・インタフェースの使用
XML問合せの結果セット・インタフェースについて理解します。
この章のトピックは、次のとおりです:
15.1 XML問合せの結果セット・インタフェースの概要
XML問合せの結果セット・インタフェース(RSI)は、XMLの問合せを実行し、XMLとして結果を戻すことができるため、SELECT
セマンティクス内で有効なSQL層および要件が回避されます。RSIは、単純なOracle Text問合せとXML結果セット記述子を使用し、その結果セット記述子に応じてXMLでヒットリストが戻されます。XML問合せのRSIは、グループ化およびカウントにSDATA
セクションを使用します。
アプリケーションでは、検索結果ページは最初の数ドキュメントのメタデータ、合計ヒット数、ワードごとのヒット数など、多くの個別の要素で構成されます。追加のコールのたびに、問合せを再解析して索引メタデータを検索するための時間がかかります。また、SQLでは、反復問合せ絞込みといった一部の検索操作が難しくなります。SQL文を構成して目的の結果を達成することが可能であっても、通常はこのようなSQLは次善の選択となります。
XML問合せRSIは、検索結果のページに必要な様々な種類のデータを同時に作成でき、オーバーヘッドを共有することでパフォーマンスを向上させます。RSIは、SQLでは表現しにくいデータ・ビューも返すことができます。
15.2 XML問合せの結果セット・インタフェースの使用
CTX_QUERY.RESULT_SET()
およびCTX_QUERY.RESULT_SET_CLOB_QUERY()
APIを使用すると、CONTAINS()
問合せを何度も実行して同じ結果を得るのではなく、単一の問合せで問合せ結果を取得できます。2つのAPIは、一方がVARCHAR2
問合せパラメータを使用し、もう一方がCLOB
問合せを使用してより長い問合せに対応できる点を除き同じです。
たとえば、検索結果ページを表示するには、まず次の情報を取得する必要があります。
-
日時および関連性でソートされた上位20個のヒット・リスト
-
指定されたOracle Text問合せのヒットの総数
-
公開日でグループ化した件数
-
作成者でグループ化した件数
検索するドキュメントを格納する次の表定義を前提とします。
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 Oracle 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リファレンス』を参照してください。
15.3 Oracle TextによるXMLのみのアプリケーションの作成
CONTAINS
句を含むSQL SELECT
文を使用してアプリケーションを作成することが一般的ですが、これは必ずしも最も効率的な方法ではありません。代替方法は、XMLベースのRSIを使用することです。このメリットは、問合せのすべての結果をフェッチしなくても、サマリー情報(ヒットの総数など)を簡単に取得できることです。
RSIを使用するには、結果セット記述子(RSD)を指定します。RSDは、戻される情報を宣言します。これは次のもので構成できます。
-
問合せ結果の合計数
-
ヒットリスト
-
SDATA
フィールドのサマリー情報
次に、ヒットリストは反復要素で構成され、そのそれぞれに次の情報が含まれます。
-
ヒットのROWID
-
ヒットのSDATAフィールド
関連項目:
15.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>
)をリクエストしています。
15.5 コロケートの識別
コロケートはドキュメント内で頻繁に共起する単語のグループです。コロケートは、指定されたキーワードに関連する他のキーワードや概念の簡単な概要を示します。問合せで他のキーワードを使用してより関連性のある結果を取得できます。
検索問合せに基づいてコロケートを識別します。問合せから返されるドキュメントごとに、検索キーワードに関連するテキストのスニペットが自動的に抽出されます。次に、これらのスニペットの語が統計メジャーを使用して問合せキーワードに関連付けられ、ドキュメント・セット全体における抽出語の発生頻度に応じて、返された各共起語にスコアが割り当てられます。
コロケートを識別するには、RSIを使用します。問合せで返される必要のある共起語の数を指定できます。また、普通名詞のコロケートを指定するか、独自性を強調するコロケートを識別するか指定することもできます。指定された検索キーワードのシノニムも返すことができます。
注意:
コロケートはBASIC_LEXER
でのみサポートされます。
コロケートを識別する手順は、次のとおりです。
- 問合せ対象のドキュメント・セット表を作成します。
- ドキュメント・セット表にOracle Text索引を作成します。
- XML問合せのRSIを使用して、コロケートを識別する問合せを定義および入力します。必要な属性を持つ
collocates
要素を含めます。
例15-1 ドキュメント・セット内のコロケートの識別
この例で、データ・セット内のドキュメントの問合せに使用されているキーワードは'Nobel'です。Oracle Textは、ドキュメント・セット内のこのキーワードの出現を検索します。結果セットに加えて、コロケートを使用して'Nobel'で共起する5つの共通語を検索します。max_words
属性を使用して、生成するコロケートの数を識別します。use_tscore
属性をTRUE
に設定して、共通語をコロケート用に識別する必要があることを指定します。コロケートを識別するためにキーワードの各側で選択する単語の数は10個です。
次に、コロケートの判別に使用される入力RSI記述子を示します。
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リファレンス』を参照してください。