13.1 ユビキタス検索とユビキタス検索索引について
ユビキタス検索では、スキーマ全体における複数オブジェクトに対する全文および範囲ベースの問合せを実行できます。ユビキタス検索索引(または単にDBMS_SEARCH
索引)を使用して、ユビキタス検索を実行できます。
ユビキタス検索索引は、表、ビューまたはJSON二面性ビューに対する全文検索を実行できるようにする、一連のプリファレンスと設定が事前定義されているJSON SEARCH INDEX
タイプです。これらの索引の作成、管理および問合せには、DBMS_SEARCH PL/SQL
パッケージを使用します。
DBMS_SEARCH
索引は、SELECT
権限を持つスキーマの表またはビューに対して作成できます。データ・ソース(つまり、表およびビュー)をこの索引に追加できます(ビューをマテリアライズする必要はない)。指定したソース内のすべての列が索引付けされ、全文または範囲ベースの検索に使用できます。
ユビキタス検索インデックスを選択する理由
この索引付け手法を使用すると、複数のオブジェクトにまたがる索引の作成、データ・ソースの追加または削除、同じ索引を使用した単一のデータ・ソース内または複数のソース間の全文または範囲ベースの検索を実行できます。これにより、以前(Oracle Database 23aiより前)は複数の個別の索引を作成し、MULTI_COLUMN_DATASTORE
またはUSER_DATASTORE
プロシージャとマテリアライズド・ビューを使用して様々なデータ・ソースを手動で結合する必要があった索引付けタスクが簡略化されます。以前は、索引がDML操作と同期されたままであることを確認するために、トリガーなどの追加のメソッドも必要でした。
DBMS_SEARCH
APIの簡略化されたセットを使用すると、次のように、データベース全体でユビキタス検索を実行できます:
-
索引の作成:
DBMS_SEARCH.CREATE_INDEX
APIでは、DBMS_SEARCH
索引を作成できます。デフォルトでは、この索引は、ワイルドカード検索を可能にする
BASIC_WORDLIST
や、全文および範囲検索の問合せを可能にするSEARCH_ON
など、キー索引プリファレンスを使用して作成されます。これらの索引は事前定義された間隔でバックグラウンドで非同期的にメンテナンスされるため、このような索引に対してSYNC_INDEX
操作とOPTIMIZE_INDEX
操作を明示的に実行する必要はありません。 -
データ・ソースの管理:
データ・ソースとして表またはビューを索引に追加することで、どの表またはビューを索引付けするか定義できます。
DBMS_SEARCH.ADD_SOURCE
APIでは、1つ以上のデータ・ソース(表、ビュー、二面性ビューなど)を様々なスキーマからこの索引に自動的に追加できます。DBMS_SEARCH.REMOVE_SOURCE
APIでは、ソースおよびそれに関連するすべてのデータを索引から削除できます。 -
結合された索引付きデータの表示:
DBMS_SEARCH.GET_DOCUMENT
APIでは、索引付けされた仮想ドキュメントを表示できます。このドキュメントでは、すべてのデータ・ソースの各行について、メタデータ値が索引付け済として表示されます。 -
複数のオブジェクトの問合せ:
DBMS_SEARCH.FIND
APIでは、指定したフィルタ条件に基づいてすべてのドキュメントのヒットリストを取得できます。
この索引は、事前定義された間隔でバックグラウンド・ジョブを作成し、DML変更を同期させ、すべてのデータ・ソースでAUTO_DAILY
モードを使用して索引を最適化します。この索引に対してSYNC_INDEX
およびOPTIMIZE_INDEX
操作を明示的に実行する必要はありません。
ユビキタス検索索引作成の概要
DBMS_SEARCH
索引を作成するには、索引名を指定してから、様々なデータ・ソースを追加します。次の図にこれを示します。
-
最初のコマンド(
DBMS_SEARCH.CREATE_INDEX
プロシージャ)では、[schema].index_name
として索引表が作成されます。[schema].index_name
という名前のユビキタス検索索引も、索引表のDATA
列に作成されます。なお、索引表名は索引名と一致します。ここでは、スキーマ所有者名(
SCOTT
)は、索引名(MYINDEX
)とともにSCOTT.MYINDEX
として指定されます。 -
2番目のコマンド(
DBMS_SEARCH.ADD_SOURCE
プロシージャ)では、様々なスキーマから1つ以上のデータ・ソース(表、ビュー、二面性ビューなど)を追加します。ここでは、このプロシージャは、Scottのスキーマにある
PRODUCTS
表およびCUSTOMERS
表のすべての列の内容をMYINDEX
表に結合します。
MYINDEX
表には次の列があります:
-
DATA (JSONデータ型):
これは空の列であり、
DBMS_SEARCH
索引を問い合せるためのプレースホルダです。データ・ソースをDATA
列に追加します。次に、CONTAINS()
、JSON_TEXTCONTAINS()
およびJSON_EXISTS
演算子を使用して、このDATA
列に対してPL/SQL問合せを実行できます。DATA
列では、この索引にデータ・ソースとして追加される表またはビューの索引付き行ごとに、次の形式のJSON表現が作成されます:{"OWNER": { "TABLE_NAME":{"COLUMN1_NAME":"COLUMN1_VALUE",…} } }
DATA
列に実際のデータは格納されないことに注意してください。かわりに、データは元の実表に存在します。この索引は、データ・ソース表を参照して、索引付けされた仮想JSONドキュメントをその場で作成します。データがフェッチおよび索引付けされた後、この列は事実上空になり、重複が回避されます。 -
METADATA (JSONデータ型):
METADATA
列は、DBMS_SEARCH
索引で、索引付けされた表またはビューの各行を一意に識別するために役立ちます。この索引にデータ・ソースを追加した後、METADATA
列には、データ・ソースの索引付き行ごとに、次の形式のJSON表現が格納されていることを確認できます:{ "OWNER" : "Table_Owner or View_Owner", "SOURCE" : "Table_Name or View_Name", "KEY" : "{PrimaryKey_COLUMN_i" : PrimaryKey_VALUE_i} }
OWNER
は、この索引にデータ・ソースとして追加された表またはビューの所有者を指定します。SOURCE
は、データ・ソースの表名またはビュー名を指定します。KEY
は、データ・ソース表のすべての主キー列で構成されます。表に主キーがない場合には、かわりにROWID
が使用されます。ただし、主キーを定義することをお薦めします。図に示すように、
METADATA
列には、索引付き行ごとに次の形式の対応するJSONエントリが格納されます:PRODUCTS
表の場合:{"OWNER":"SCOTT","SOURCE":"PRODUCTS","KEY":{"ID":1}} {"OWNER":"SCOTT","SOURCE":"PRODUCTS","KEY":{"ID":2}}
CUSTOMERS
表の場合:{"OWNER":"SCOTT","SOURCE":"CUSTOMERS","KEY":{"ID":5}} {"OWNER":"SCOTT","SOURCE":"CUSTOMERS","KEY":{"ID":9}}
ノート:
DBMS_SEARCH
索引では、サポートされているすべてのSQLデータ型(Object Type
列を含む)がJSONオブジェクトとして格納されます(XMLTYPE
およびLONG
データ型を除く)。したがって、表またはビューは、XMLTYPE
またはLONG
データ型の列がある場合、データ・ソースとして追加できません。 -
OWNER、SOURCE、KEY (VARCHAR2データ型):
METADATA
列の各JSONキー(つまり、OWNER
、SOURCE
およびKEY
)は、MYINDEX
表内の別々の仮想列でもあります。MYINDEX
表はOWNER
およびSOURCE
によってパーティション化されていることに注意してください。特定のデータ・ソースを問い合せるときは、OWNER
およびSOURCE
の仮想列にWHERE
句条件を追加すると、パーティション・プルーニングを使用して問合せ検索をそのソースの特定のパーティションに限定できます。ノート:
DBMS_SEARCH
索引に追加するすべてのデータ・ソース(表、ビュー、ビュー定義の各表など)には、少なくとも1つのPrimary Key
列が含まれている必要があります。外部キーがあるビュー・ソースに含まれている各表には、その表で定義されている関連する主キーを参照するForeign Key
制約も必要です。ソース表に主キーがない場合には、かわりにROWID
が使用されます。
索引付きデータの問合せ
前述したとおり、DBMS_SEARCH.GET_DOCUMENT
プロシージャを使用して、仮想ドキュメントを問い合せることにより、元の実表から抽出されたすべての内容を表示できます。このドキュメントには、データ・ソースとして索引に追加される表またはビューの索引付き行ごとにJSON表現が含まれています。
DBMS_SEARCH.GET_DOCUMENT
の構文は次のとおりです:
SELECT DBMS_SEARCH.GET_DOCUMENT('[schema].index_name', METADATA)
from [schema].index_name;
たとえば、前述したPRODUCTS
およびCUSTOMERS
ソース表のシナリオを使用すると、次の文は、結合されたメタデータ値がMYINDEX
索引で索引付けされた仮想ドキュメントを返します:
SELECT DBMS_SEARCH.GET_DOCUMENT('SCOTT.MYINDEX',METADATA)
from SCOTT.MYINDEX;
DBMS_SEARCH.GET_DOCUMENT('SCOTT.MYINDEX', METADATA)
-----------------------------------------------------------------
{
"SCOTT" :
{
"PRODUCTS" :
{
"ID" : 1,
"PRICE" : 10,
"DESCRIPTION" : "simple widget"
}
}
}
{
"SCOTT" :
{
"PRODUCTS" :
{
"ID" : 2,
"PRICE" : 2000,
"DESCRIPTION" : "shiny thing"
}
}
}
{
"SCOTT" :
{
"CUSTOMERS" :
{
"ID" : 5,
"FIRSTNAME" : "Robert",
"LASTNAME" : "Smith"
}
}
}
{
"SCOTT" :
{
"CUSTOMERS" :
{
"ID" : 9,
"FIRSTNAME" : "John",
"LASTNAME" : "Doe"
}
}
}
CONTAINS
、JSON_TEXTCONTAINS
およびJSON_EXISTS
演算子を使用して、索引に対して問合せを実行できるようになりました。
DBMS_SEARCHディクショナリ・ビュー
次のディクショナリ・ビューを使用して、ユビキタス検索索引を調べることができます:
-
USER_DBMS_SEARCH_INDEXES
: ユーザーのスキーマに作成された索引に関する情報を問い合せます。 -
ALL_DBMS_SEARCH_INDEXES
: 各索引所有者に対応する、既存のすべての索引に関する情報を問い合せます。 -
USER_DBMS_SEARCH_INDEX_SOURCES
: ユーザーのスキーマに作成された、索引に追加されたデータ・ソースに関する情報を問い合せます。 -
ALL_DBMS_SEARCH_INDEX_SOURCES
: 各索引所有者に対応する、索引に追加された既存のすべてのデータ・ソースに関する情報を問い合せます。