16 DBMS_SEARCHパッケージ

DBMS_SEARCH PL/SQLパッケージには、ユビキタス検索索引を作成、管理および問い合せるためのプロシージャおよびファンクションが用意されています。

様々な個々の索引を作成したり、USER_DATASTOREまたはMULTI_COLUMN_DATASTOREプロシージャをマテリアライズド・ビューとともに手動で定義するのではなく、ユビキタス検索索引を作成して、複数の表またはビューを単一の索引に自動的に統合できます。この索引を使用すると、スキーマ全体における複数オブジェクトに対して全文検索および範囲ベースの検索を実行できます。

ノート:

これらの各APIの例に加えて、『Oracle Textアプリケーション開発者ガイド』に示すように、エンドツーエンドの様々なシナリオ例を実行できます。
名前 説明

CREATE_INDEX

ユビキタス検索索引を作成します。

ADD_SOURCE

表、ビューまたは二面性ビューをデータ・ソースとして索引に追加します。

REMOVE_SOURCE

データ・ソースおよび関連するすべてのデータを索引から削除します。

DROP_INDEX

索引および関連するすべてのデータをデータベースから削除します。

GET_DOCUMENT

指定されたソース・メタデータの、索引付けされた仮想JSONドキュメントを返します。

FIND

ヒットリストを取得し、指定されたフィルタ条件に基づいてJSONドキュメントの集計をファセット化します。

16.1 CREATE_INDEX

DBMS_SEARCH.CREATE_INDEXプロシージャにより、複数のスキーマ・オブジェクトにわたって全文検索および範囲ベースの検索を実行するためのユビキタス検索索引(またはDBMS_SEARCH索引)が作成されます。

構文

索引タイプは、表、ビューおよび二面性ビューに対して全文検索を実行するためのプリファレンスおよび設定の事前定義済セットで有効になっているJSON検索索引です。

DBMS_SEARCH.CREATE_INDEX(
    index_name  IN  VARCHAR2,
    tablespace  IN  VARCHAR2  DEFAULT,
    datatype    IN  VARCHAR2  DEFAULT
);
index_name

作成するDBMS_SEARCH索引の名前を指定します。スキーマの所有者名と索引名を次のように指定することもできます:

[schema].index_name

tablespace

索引または索引パーティションを含む表領域の名前を指定します。

datatype

索引を作成するDATA列のデータ型を指定します。使用可能な値はJSONおよびOSONです。

デフォルト値はJSONに設定されているため、datatype引数を指定する必要があるのは、このデフォルトをオーバーライドする場合のみです。

ノート

  • データ・ソースとして表またはビューを索引に追加することで、どの表またはビューを索引付けするか定義できます。これらの表またはビューのすべての列が索引付けされます。データ・ソースを管理するには、DBMS_SEARCH.ADD_SOURCEおよびDBMS_SEARCH.REMOVE_SOURCEプロシージャを使用します。

  • DBMS_SEARCH索引は、デフォルトの次の索引付けプリファレンスを使用して作成されます:

    プリファレンス 説明

    WILDCARD_INDEX

    高速ワイルドカード検索のためにワイルドカード索引付けを有効にします。

    BASIC_WORDLIST

    ステミングとファジー・マッチングを有効にします。

    SEARCH_ON

    特定のデータ型に対する全文検索問合せと範囲検索問合せの両方を許可します。サポートされているデータ型は、NUMBER (数値の索引付けの場合)およびTIMESTAMP (日時値の索引付けの場合)です。

    SYNCおよびOPTIMIZE

    事前定義された間隔でバックグラウンド・ジョブを作成し、DML変更を自動的に同期させ、すべてのデータ・ソースでAUTO_DAILYモードを使用して索引を最適化します。

    この索引に対してSYNC_INDEXおよびOPTIMIZE_INDEX操作を明示的に実行する必要はありません。

  • この索引を問い合せるには、INDEX_NAME表に対してCONTAINS()JSON_TEXTCONTAINS()およびJSON_EXISTS演算子を使用します。

  • 次のDBMS_SEARCHディクショナリ・ビューを使用して、これらの索引を調べることができます:

    • USER_DBMS_SEARCH_INDEXES: ユーザーのスキーマに作成されたDBMS_SEARCH索引に関する情報を問い合せます。

    • ALL_DBMS_SEARCH_INDEXES: 各索引所有者に対応する、既存のすべてのDBMS_SEARCH索引に関する情報を問い合せます。

    • USER_DBMS_SEARCH_INDEX_SOURCES: ユーザーのスキーマに作成された、DBMS_SEARCH索引に追加されたデータ・ソースに関する情報を問い合せます。

    • ALL_DBMS_SEARCH_INDEX_SOURCES: 各索引所有者に対応する、DBMS_SEARCH索引に追加された既存のすべてのデータ・ソースに関する情報を問い合せます。

この例では、index_nametablespaceおよびdatatype引数を指定します。ここでは、スキーマ所有者名を索引名とともにSCOTT.MYINDEXと指定します。

CREATE TABLESPACE tbs_02 DATAFILE 'dt.dbf' size 100MB segment space management auto;

exec DBMS_SEARCH.CREATE_INDEX('SCOTT.MYINDEX','tbs_02','JSON');

16.2 ADD_SOURCE

DBMS_SEARCH.ADD_SOURCEプロシージャにより、様々なスキーマからの1つ以上のデータ・ソース(表またはビュー)をDBMS_SEARCH索引に追加します。

構文

DBMS_SEARCH.ADD_SOURCE(
  index_name   IN  VARCHAR2,
  source_name  IN  VARCHAR2
);
index_name
表またはビューを追加する索引の名前を指定します。[schema].index_nameと指定することもできます。
source_name
索引に追加する表、ビューまたは二面性ビューの名前を指定します。[schema].table_or_view_nameと指定することもできます。

ノート

  • データ・ソースを追加するには、索引所有者に、そのソースへのSELECTおよびDMLアクセス権が必要です。ユーザーには、CTXAPP権限も必要です。

  • DBMS_SEARCH索引に追加するすべてのデータ・ソース(表、ビュー、ビュー定義の各表など)には、少なくとも1つのPrimary Key列が含まれている必要があります。外部キーがあるビュー・ソースに含まれている各表には、その表で定義されている関連する主キーを参照するForeign Key制約も必要です。

    ソース表に主キーがない場合には、かわりにROWIDが使用されます。ただし、主キーを定義することをお薦めします。

  • DBMS_SEARCH索引では、サポートされているすべてのSQLデータ型(Object Type列を含む)がJSONオブジェクトに格納されます(XMLTYPEおよびLONGデータ型を除く)。つまり、表またはビューは、XMLTYPEまたはLONGデータ型の列がある場合は、データ・ソースとして索引に追加できません。JSONデータ型の許容される最大長は32 MBです。

  • USER_DBMS_SEARCH_INDEX_SOURCESおよびALL_DBMS_SEARCH_INDEX_SOURCESディクショナリ・ビューを使用すると、DBMS_SEARCH索引に追加されたデータ・ソースに関する情報を問い合せることができます。

exec DBMS_SEARCH.ADD_SOURCE('MYINDEX','MYTABLE');
exec DBMS_SEARCH.ADD_SOURCE('MYINDEX','MYVIEW');
exec DBMS_SEARCH.ADD_SOURCE('DOCUSER.MYINDEX','DOCUSER.MYTABLE');

16.3 REMOVE_SOURCE

DBMS_SEARCH.REMOVE_SOURCEプロシージャにより、DBMS_SEARCH索引から1つ以上のデータ・ソース(表またはビュー)を削除します。

このプロシージャを実行すると、索引付けされたすべてのデータが削除され、関連するデータ・ソース(表またはビュー)に対する索引付け操作またはメンテナンス操作が停止されます。

構文

DBMS_SEARCH.REMOVE_SOURCE(
  index_name VARCHAR2, 
  source_name VARCHAR2);
index_name
ビューまたは表を削除する索引の名前を指定します。
source_name
削除する表またはビューの名前を指定します。

exec DBMS_SEARCH.REMOVE_SOURCE('MYINDEX','MYTABLE');

16.4 DROP_INDEX

DBMS_SEARCH.DROP_INDEXプロシージャにより、DBMS_SEARCH索引、およびそれに関連するすべてのデータをデータベースから削除します。

構文

DBMS_SEARCH.DROP_INDEX(
  INDEX_NAME VARCHAR2);
index_name
削除する索引の名前を指定します。

exec DBMS_SEARCH.DROP_INDEX('MYINDEX');

16.5 GET_DOCUMENT

DBMS_SEARCH.GET_DOCUMENTプロシージャでは、索引付けされたデータ・ソース(表またはビュー)の特定の行について、JSON検索索引で索引付けされているのと同じように、索引付けされた仮想JSONドキュメントが返されます。

構文

DBMS_SEARCH索引は、関連するデータ・ソース表を参照して、仮想索引付きドキュメントを動的に作成します。このドキュメントには、この索引にデータ・ソースとして追加される表またはビューの索引付き行ごとにJSON表現が含まれています。このようにして、元の実表から抽出されたすべてのコンテンツを表示できます。

DBMS_SEARCH.GET_DOCUMENT(
  index_name VARCHAR2,
  metadata JSON
);
index_name

データを取得する索引の名前を指定します。

metadata

JSONメタデータ値(OWNERSOURCEKEYなど)を指定します。INDEX_NAME表のMETADATA列に基づいてメタデータ形式を指定する必要があります。

SELECT DBMS_SEARCH.GET_DOCUMENT('MYINDEX',METADATA) from MYINDEX;

16.6 FIND

DBMS_SEARCH.FINDプロシージャにより、ヒットリストを取得し、指定された、例による問合せ(QBE)フィルタ条件に基づいて、JSONドキュメントの集計をファセット化します。

JSONデータの様々なフィールドに対して集計を計算できます。この問合せでは、ファセット・ナビゲーションおよび集計をサポートするJSON結果セット・インタフェースに、検索結果がリストされます。

構文

DBMS_SEARCH.FIND(
  index_name VARCHAR2, 
  search_QBE JSON);
index_name

問合せを実行する索引の名前を指定します。

search_QBE

JSONでのresult_set_descriptorパラメータ値を指定します。結果セットに含む内容を示します。

JSON形式の入力結果セット記述子は、$query$searchおよび$facet部分からなります:
{
  "$query":text query and filter conditions,
  "$search":search result specifications,
  "$facet":faceted result specifications	
}

これらの各JSONオブジェクトの詳細は、「JSON形式の入力結果セット記述子」を参照してください。

JSON形式の出力結果セット記述子は次の部分からなります:

"$count":number
"$hit":[ hit_object_1, ..., hit_object_i , ... ]
"$facet":[ facet_object_1, ..., facet_object_i, ...]

これらの各JSONオブジェクトの詳細は、「JSON形式の結果セットの出力」を参照してください。

表を作成し、値を移入します。
SET FEEDBACK 1
SET NUMWIDTH 10
SET LINESIZE 80
SET TRIMSPOOL ON
SET TAB OFF
SET PAGESIZE 100
connect sys/knl_example as sysdba;
Connected.

grant connect,resource, unlimited tablespace, ctxapp
  to u1 identified by u1;
Grant succeeded.

connect u1/u1;
Connected.

create table tbl(id number primary key, jsn_col clob check(jsn_col is json));
Table created.

INSERT INTO tbl
  VALUES (1,'{ "zebra" : { "price" : [2000,1000],
                         "name" : "Marty",
                         "stripes" : ["Dark","Light"],
                         "handler" : "Bob", "sold" : true }}');
1 row created.

INSERT INTO tbl
  VALUES (2,'{ "zebra" : { "rating": 5, "price" : 1000,
                         "name" : "Zigby",
                         "stripes" : ["Light","Grey"],
                         "handler" : "Handy Marty", "sold" : "true" }}');
1 row created.
 
 INSERT INTO tbl
   VALUES (3,'{ "zebra" : { "rating": 4.5, "price" : 3000,
                          "name" : "Zigs",
                          "stripes" : ["Grey","Dark"],
                          "handler" : "Handy Marty", "sold" : false }}');
1 row created.
 
 INSERT INTO tbl
   VALUES (4,'{ "zebra" : { "rating": "4.5", "price" : "3000",
                          "name" : "Zigs",
                          "stripes" : ["Grey","Dark"],
                          "handler" : "Handy Marty", "sold" : null }}');
1 row created.
 
 commit;
Commit complete.
DBMS_SEARCH.CREATE_INDEXプロシージャを使用してDBMS_SEARCH索引を作成し、索引にソース表を追加します:
SQL> exec DBMS_SEARCH.CREATE_INDEX('JIDX');
PL/SQL procedure successfully completed.
SQL> exec DBMS_SEARCH.ADD_SOURCE('JIDX','TBL');
PL/SQL procedure successfully completed.
SQL> 
DBMS_SEARCH.FINDプロシージャを実行します:
Query: All zebras having name starting with Zig or having name Marty and
having a price greater than equal to 2000
Facets: For all zebras that satisfy the query, do the following
--   1. Get the count of zebras per zebra handler
--   2. Get the minimum zebra rating
--   3. Get the count of zebras for each unique stripe color
select DBMS_SEARCH.FIND('JIDX',JSON('
  {
    "$query": { "$and" : [
                    { "U1.TBL.JSN_COL.zebra.name" : { "$contains" : "Zig% or Marty" } },
                    { "U1.TBL.JSN_COL.zebra.price" : { "$gte" : 2000 } }
                  ]
                },
      "$facet" : [
        { "$uniqueCount" : "U1.TBL.JSN_COL.zebra.handler" },
        { "$min" : "U1.TBL.JSN_COL.zebra.rating" },
        { "$uniqueCount" : "U1.TBL.JSN_COL.zebra.stripes" }
      ]
    }'));
出力内容は次のようになります。

FIND_RESULT
--------------------------------------------------------------------------------
{
  "$count" : 3,
  "$facet" :
  [
    {
      "U1.TBL.JSN_COL.zebra.handler" :
      [
        {
          "value" : "Handy Marty",
          "$uniqueCount" : 2
        },
        {
          "value" : "Bob",
          "$uniqueCount" : 1
        }
      ]
    },
    {
      "U1.TBL.JSN_COL.zebra.rating" :
      {
        "$min" : 4.5
      }
    },
    {
      "U1.TBL.JSN_COL.zebra.stripes" :
      [
        {
          "value" : "Dark",
          "$uniqueCount" : 3
        },
        {
          "value" : "Grey",
          "$uniqueCount" : 2
        },
        {
          "value" : "Light",
          "$uniqueCount" : 1
        }
      ]
    }
  ]
}
1 row selected.
connect sys/knl_example as sysdba;
Connected.
drop user u1 cascade;
User dropped.