15.3 結果セット・インタフェースを使用したファセットの問合せ
Oracle Databaseリリース18から、指定されたファセットのリストのグループ・カウント操作が用意されています。bucketby
属性の値をsingle
に設定して使用することで、単一の値ごとにグループ・カウントを取得できます。topn
、sortby
およびorder
属性もサポートされています。Oracle Databaseリリース21c以降では、group
要素の子要素であるrange
要素を使用することで、ファセットの数値および変数文字値の範囲についてグループ・カウントを取得できます。
bucketby属性
有効な属性はsingle
とcustom
です。
-
'single'モードでは、ファセットのすべての一意の値のリスト、および各値のドキュメント・カウントが生成されます。
-
'custom'モードでは、数値の範囲のドキュメント・カウントが生成されます。
count要素(単一カウント)
次の例では、いくつかの行がmytab
表に挿入されます。一部の行にはファセット<B>
の値が2つあり、一部の行には単一の値があります。
begin
insert into mytab values (1, '<B>1.234</B><B>5</B>');
insert into mytab values (2, '<B>1.432</B>');
insert into mytab values (3, '<B>2.432</B><B>6</B>');
insert into mytab values (4, '<B>2.432</B>');
end;
単一件数では、一意のそれぞれの値と、その値を持つドキュメントの数を表示します。
<ctx_result_set>
<groups sdata="SEC01">
<group value="2.432"><count>2</count></group>
<group value="1.234"><count>1</count></group>
<group value="5"><count>1</count></group>
<group value="6"><count>1</count></group>
<group value="1.432"><count>1</count></group>
</groups>
</ctx_result_set>
ドキュメント1が削除されると、次のような結果になります。
<ctx_result_set>
<groups sdata="SEC01">
<group value="2.432"><count>2</count></group>
<group value="6"><count>1</count></group>
<group value="1.432"><count>1</count></group>
</groups>
</ctx_result_set>
range要素
range
要素では、start、greaterthan、end
およびlessthan
属性がサポートされています。start
およびgreaterthan
属性では、範囲の開始値を指定します。end
およびlessthan
属性では、範囲の終了値を指定します。
範囲は相互に重なってもかまいません。たとえば、<range start="1" end="2"/>
および<range start="2" end="3"/>
です。範囲は片方のみ指定することもできます。たとえば、開始値または終了値のみを指定できます。range
要素の属性を指定しない場合、すべての結果が返されます。
例15-2 ファセットの範囲のグループ・カウントの取得
products
という表を作成し、それにデータを移入します。
drop table products;
create table products(name varchar2(60), vendor varchar2(60), rating number, price number);
insert all
into products values ('cherry red shoes', 'first vendor', 5, 129)
into products values ('bright red shoes', 'first vendor', 4, 109)
into products values ('more red shoes', 'second vendor', 5, 129)
into products values ('shoes', 'third vendor', 5, 109)
into products values ('dark red shoes', 'fourth vendor', 3, 98)
into products values ('light red shoes', 'fifth vendor', 2, 49)
select * from dual;
ds
という名前のMULTI_COLUMN_DATASTORE
プリファレンスを作成して、ファセットとして使用するよう他の各種列を索引(name)
に取り込みます。
exec ctx_ddl.drop_preference ('ds')
exec ctx_ddl.create_preference('ds', 'MULTI_COLUMN_DATASTORE')
exec ctx_ddl.set_attribute ('ds', 'COLUMNS', 'name, vendor, rating, price')
sg
という名前のセクション・グループを作成し、各列がファセットとして処理されるようにoptimized_for search
属性を有効にします。
exec ctx_ddl.drop_section_group ('sg')
exec ctx_ddl.create_section_group ('sg', 'BASIC_SECTION_GROUP')
exec ctx_ddl.add_sdata_section ('sg', 'rating', 'rating', 'NUMBER')
exec ctx_ddl.add_sdata_section ('sg', 'price', 'price', 'NUMBER')
exec ctx_ddl.add_sdata_section ('sg', 'vendor', 'vendor', 'VARCHAR2')
exec ctx_ddl.set_section_attribute('sg', 'rating', 'optimized_for', 'SEARCH')
exec ctx_ddl.set_section_attribute('sg', 'price', 'optimized_for', 'SEARCH')
exec ctx_ddl.set_section_attribute('sg', 'vendor', 'optimized_for', 'SEARCH')
name
に索引を作成し、parameters
句を使用してプリファレンスを指定します。
create index mytab_idx on products (name)
indextype is ctxsys.context
parameters ('datastore ds section group sg');
bucketby
属性をcustom
に設定し、range
要素の値を指定して、製品名'red shoes'を問い合せます。
set long 500000
set pagesize 0
variable displayrs clob;
declare
rs clob;
begin
ctx_query.result_set('mytab_idx', 'red shoes', '<ctx_result_set_descriptor>
<group sdata="rating" bucketby="custom">
<range start="1" lessthan="10"/>
<range start="10" lessthan="20"/>
<range start="20"/>
</group>
<group sdata="price" bucketby="custom">
<range end="1"/>
<range greaterthan="1" end="10"/>
<range greaterthan="10" end="100"/>
<range greaterthan="100"/>
</group>
<group sdata="vendor" bucketby="custom">
<range greaterthan="a"/>
<range start="s"/>
<range end="f"/>
</group>
</ctx_result_set_descriptor>',
rs);
select xmlserialize(Document XMLType(rs) as clob indent size=2) into :displayrs from dual;
dbms_lob.freetemporary(rs);
end;
/
select :displayrs from dual;
出力は次のようになります。
<ctx_result_set>
<groups sdata="RATING">
<group value="range" start="1" lessthan="10">
<count>5</count>
</group>
<group value="range" start="10" lessthan="20">
<count>0</count>
</group>
<group value="range" start="20" end="5">
<count>0</count>
</group>
</groups>
<groups sdata="PRICE">
<group value="range" start="49" end="1">
<count>0</count>
</group>
<group value="range" greaterthan="1" end="10">
<count>0</count>
</group>
<group value="range" greaterthan="10" end="100">
<count>2</count>
</group>
<group value="range" greaterthan="100" end="129">
<count>3</count>
</group>
</groups>
<groups sdata="VENDOR">
<group value="range" greaterthan="a" end="second vendor">
<count>5</count>
</group>
<group value="range" start="s" end="second vendor">
<count>1</count>
</group>
<group value="range" start="fifth vendor" end="f">
<count>0</count>
</group>
</groups>
</ctx_result_set>
topn属性
-
有効な属性値は、0より大きい正の数です。
-
この属性は、上位
n
件のファセット値とそのカウントのみを返すよう指定します。 -
グループ・カウントにより、
sortby
属性がvalue
に設定されている場合の除き、返される上位n
件の値が決定されます。その場合、値はデータ型に従ってソートされ、ソートの上位n
件の結果が返されます。ソートにおいては順序属性が考慮されます。 -
デフォルトでは、結果はグループ・カウントを基準として降順でソートされます。
-
カウントに同順位がある場合、この同順位内のファセット値の順序は保証されません。
sortbyおよびorder属性
sortby
では、count
およびvalue
属性がサポートされています。
-
count
はグループ件数(数値)でソートします。これはデフォルトです。 -
value
は、データ型に応じて、値でソートします。
order
では、ASC
(昇順)およびDESC
(降順) (こちらがデフォルト)がサポートされています。
選択されていない場合、デフォルトはcount DESC
です。
この例は、bucketby
がsingle
に設定されている場合の数値ファセットのグループ化を示しています。ここで、mytab_idx
は索引の名前、text
が問合せであり、グループSDATA
がファセットを要求しています。
begin
ctx_query.result_set('mytab_idx', 'text',
'<ctx_result_set_descriptor>
<group sdata="sec01" topn = "4" sortby = "value" order="asc" bucketby="single">
<count/>
</group>
</ctx_result_set_descriptor>'
:rs);
end;
次に、sortby
属性がcount
ではなくvalue
に設定されているために、値がアルファベット順にリストされているサンプル出力を示します。order
属性がasc
に設定されているため、値は昇順(ABCからXYZ)で表示されます。topn
属性が4
に設定されているため、4つの値のみが表示されます。
<ctx_result_set>
<group SDATA="SEC01">
<group value="ABC"><count>2</count>
</group>
<group value="DEF"><count>1</count>
</group>
<group value="GHI"><count>10</count>
</group>
<group value="XYZ"><count>1</count>
</group>
</ctx_result_set>