15.2 ファセットとしてのセクションの定義
SDATA
は構造化データを参照します。グループ件数つまりファセットは、optimized_for
属性を'search'または'sort and search'に設定して作成するSDATA
セクションでサポートされています。MULTI_COLUMN_DATASTORE
プリファレンスで、データがoptimized_for search
SDATA
として指定されたタグや列の間にあると、そのデータは自動的にファセット・データとして索引付けされます。宣言されたタイプと一致しないデータは、特定の行の索引付けエラーをそのときに処理しているのと同じフレームワークに基づいて処理されます。
例
次の文では、いくつかのタグ付けされたデータが表のVARCHAR2
列に挿入されます。後から、ここで使用されたタグに基づいてデータを収集するためのSDATA
セクションを定義できます。
-
バイナリfloatやバイナリdoubleにはタグprice:
insert into mytab values (1, 'red marble' <price>1.23</price>');
-
タイム・スタンプにはタグT:
insert into mytab values (1,'blue marbles <T>2012-12-05T05:20:00</T>');
次の文では、セクション・グループが作成され、様々なSDATA
セクション・グループが追加されます。セクションの定義には、そのセクションが属するセクション・グループ、セクションの名前、検索するタグ、およびデータ型が含まれます。
exec ctx_ddl.create_section_group('sg','BASIC_SECTION_GROUP')
exec ctx_ddl.add_SDATA_section('sg','sec01','name', 'varchar2')
exec ctx_ddl.add_SDATA_section('sg','sec02','count', 'number')
exec ctx_ddl.add_SDATA_section('sg','sec03','date', 'date')
exec ctx_ddl.add_SDATA_section('sg','sec04','timestamp', 'timestamp')
exec ctx_ddl.add_SDATA_section('sg','sec05','new price', 'binary_double')
exec ctx_ddl.add_SDATA_section('sg','sec06','old price','binary_float')
exec ctx_ddl.add_SDATA_section('sg','sec07','timestamp','timestamp with time zone')
ファセットに付けた名前が'sec01'
で、'name'
タグは、索引付けされたドキュメント内に出現する実際のタグ名です。'date'
、'timestamp'
および'timestamp with time zone'
データ型では、入力データは標準ISO形式である必要があります。
関連項目:
標準ISOフォーマットの詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。
例15-1 ファセット・ナビゲーションの使用
次の文では、products
という名前の表が作成されます。
drop table products;
create table products(name varchar2(60), vendor varchar2(60), rating number, price number, mydate date);
次の文は、値をproducts
に挿入します。
insert all
into products values ('cherry red shoes', 'first vendor', 5, 129, sysdate)
into products values ('bright red shoes', 'first vendor', 4, 109, sysdate)
into products values ('more red shoes', 'second vendor', 5, 129, sysdate)
into products values ('shoes', 'third vendor', 5, 109, sysdate)
select * from dual;
次の文は、ds
という名前のMULTI_COLUMN_DATASTORE
プリファレンスを作成して、ファセットとして使用するよう他の各種列を索引(name
)に取り込んでいます。
/*A MULTI_COLUMN_DATASTORE automatically adds tags by default so that the text to be indexed looks like
'<name>cherry red shoes</name><vendor>first vendor</vendor><rating> .... '*/
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, mydate')
ノート:
Oracleでは、binary_float、binary_double、timestamp
およびtimestamp with timezone
のデータ型を持つ表の列は許可されていません。そのため、このようなデータ型をMULTI_COLUMN_DATASTORE
で使用することは困難です。それでも、これらのデータ型のタグ付きデータがドキュメントに含まれている場合はファセットを作成できます。あるいは、'timestamp'列は'date'に変換し、binary_float
、binary_double
は'number'として格納できます。
次の文では、sg
という名前のセクション・グループを作成し、各列のoptimized_for search
属性がファセットとして処理されるようにします。
/* A Section Group is created to specify the data type of each column (varchar2 is the default) and
how each column that is brought into the index should be used.*/
exec ctx_ddl.drop_section_group ('sg')
exec ctx_ddl.create_section_group ('sg', 'BASIC_SECTION_GROUP')
exec ctx_ddl.add_sdata_section ('sg', 'vendor', 'vendor', 'VARCHAR2')
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', 'mydate', 'mydate', 'DATE')
exec ctx_ddl.set_section_attribute('sg', 'vendor', 'optimized_for', 'SEARCH')
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', 'mydate', 'optimized_for', 'SEARCH')
次の文では、name
に索引が作成され、PARAMETERS
句を使用してプリファレンスを指定します。
CREATE INDEX product_index ON products (name)
INDEXTYPE IS ctxsys.context
PARAMETERS ('datastore ds section group sg');
次の文では製品名'red shoes'を問い合せ、計算のファセットを指定できます。count
属性は製品の問合せに一致する品目の合計数を示します。結果セット・インタフェースでは、一致するアイテムが最も多い上位ベンダー、最安値、および最新の着荷など、様々な要件を指定します。
set long 500000
set pagesize 0
variable displayrs clob;
declare
rs clob;
begin
ctx_query.result_set('product_index', 'red shoes', '<ctx_result_set_descriptor>
<count/>
<group sdata="vendor" topn="5" sortby="count" order="desc">
<count exact="true"/>
</group>
<group sdata="price" topn="3" sortby="value" order="asc">
<count exact="true"/>
</group>
<group sdata="mydate" topn="3" sortby="value" order="desc">
<count exact="true"/>
</group>
</ctx_result_set_descriptor>',
rs);
/* Pretty-print the result set (rs) for display purposes.
It is not required if you are going to manipulate it in XML.*/
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>
<count>3</count>
<groups sdata="VENDOR">
<group value="first vendor">
<count>2</count>
</group>
<group value="second vendor">
<count>1</count>
</group>
</groups>
<groups sdata="PRICE">
<group value="109">
<count>1</count>
</group>
<group value="129">
<count>2</count>
</group>
</groups>
<groups sdata="MYDATE">
<group value="2017-12-06 05:44:54">
<count>3</count>
</group>
</groups>
</ctx_result_set>