15.3 結果セット・インタフェースを使用したファセットの問合せ

Oracle Databaseリリース18から、指定されたファセットのリストのグループ・カウント操作が用意されています。bucketby属性の値をsingleに設定して使用することで、単一の値ごとにグループ・カウントを取得できます。topnsortbyおよびorder属性もサポートされています。Oracle Databaseリリース21c以降では、group要素の子要素であるrange要素を使用することで、ファセットの数値および変数文字値の範囲についてグループ・カウントを取得できます。

bucketby属性

有効な属性はsinglecustomです。

  • '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です。

この例は、bucketbysingleに設定されている場合の数値ファセットのグループ化を示しています。ここで、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>