先日、RDFグラフをAPEXで扱う記事を書いたのですが、基本的すぎて面白みがないと感じたので、RDFグラフの検索にバインド変数を使ってみました。アプリケーションの作成に当たっては、マニュアルRDFナレッジ・グラフ開発者ガイドに記載されている家系の情報を使っています。
以下のような動作をするアプリケーションを作成します。人の名前を入力すると、上の対話レポートにその人の子供を一覧し、下の対話モード・レポートには孫を一覧します。
アプリケーション開発に使用する環境は、以前の記事と同じです。データの準備やSQL の取り出しは手元で動かしているOracle Database 21c XEを使います。APEXアプリケーションはAutonomous Databaseに作成します。
両方の環境ともに、APEXDEVというスキーマで作業を行います。
Oracle Database 21c XEにロードしたグラフのデータは、DataPumpを使ってAutonomous Databaseへ移行します。
データの準備とSQLの取り出し
Oracle Database 21c XEに家系の情報をロードし、APEXアプリケーションに埋め込むSQLの取り出しを行います。
もしネットワークNET1が作成されていたら、削除しておきます。まっさらな環境で作業を行なうことで、エラーが発生する可能性を減らしておきます。
家系の情報をロードします。以下の作業を行なっています。
- SEM_APIS.CREATE_SEM_NETWORKを呼び出し、ネットワークNET1を作成。
- SEM_APIS.CRAETE_SEM_MODELを使用してモデルfamilyを作成。
- SEM_APIS.UPDATE_MODELを呼び出し、家系のスキーマを定義しデータを投入。
- SEM_APIS.CREATE_RULEBASEを呼び出し、grandParentOfのルール(parentOfのparentOf)を定義する。
- SEM_APIS.CREATE_ENTAILMENTを呼び出し、伴意(ルール索引)を作成する。
- SEM_MATCHを使った検索を実行し、動作の確認をする。
GRANDFATHER
--------------------------------------------------------------------------------
GRANDCHILD
--------------------------------------------------------------------------------
<http://www.example.org/family/John>
<http://www.example.org/family/Cathy>
<http://www.example.org/family/John>
<http://www.example.org/family/Jack>
<http://www.example.org/family/John>
<http://www.example.org/family/Tom>
<http://www.example.org/family/John>
<http://www.example.org/family/Cindy>
?s=<http://www.example.org/family/Martha>
|-->?c=<http://www.example.org/family/Cindy>
|-->?c=<http://www.example.org/family/Tom>
?s=<http://www.example.org/family/Sammy>
|-->?c=<http://www.example.org/family/Jack>
|-->?c=<http://www.example.org/family/Cathy>
?s=<http://www.example.org/family/John>
|-->?c=<http://www.example.org/family/Cindy>
|-->?c=<http://www.example.org/family/Jack>
|-->?c=<http://www.example.org/family/Cathy>
|-->?c=<http://www.example.org/family/Tom>
データの移行
SQL> grant create any directory to apexdev;
Grant succeeded.
SQL>
SQL> create directory dump_dir as '/home/oracle';
Directory created.
SQL>
$ expdp apexdev/********@localhost/xepdb1 directory=dump_dir dumpfile=rdf.dmp version=19
Export: Release 21.0.0.0.0 - Production on Thu Dec 2 14:50:38 2021
Version 21.3.0.0.0
Copyright (c) 1982, 2021, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Starting "APEXDEV"."SYS_EXPORT_SCHEMA_01": apexdev/********@localhost/xepdb1 directory=dump_dir dumpfile=rdf.dmp version=19
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/FUNCTIONAL_INDEX/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/SEQUENCE/SEQUENCE
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/GRANT/OWNER_GRANT/OBJECT_GRANT
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/PROCEDURE/PROCEDURE
Processing object type SCHEMA_EXPORT/PROCEDURE/GRANT/OWNER_GRANT/OBJECT_GRANT
Processing object type SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDURE
Processing object type SCHEMA_EXPORT/VIEW/VIEW
Processing object type SCHEMA_EXPORT/VIEW/GRANT/OWNER_GRANT/OBJECT_GRANT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/INDEX/FUNCTIONAL_INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Processing object type SCHEMA_EXPORT/VIEW/TRIGGER
. . exported "APEXDEV"."NET1#RDF_LINK$":"MODEL_2" 23.95 KB 219 rows
. . exported "APEXDEV"."NET1#RDF_VALUE$" 23.67 KB 94 rows
. . exported "APEXDEV"."NET1#RDF_RULEBASE$" 6.585 KB 9 rows
. . exported "APEXDEV"."NET1#RDF_CLIQUE$":"MODEL_0" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RDF_COLLISION$" 5.070 KB 1 rows
. . exported "APEXDEV"."NET1#RDF_CRS_URI$" 293.2 KB 5688 rows
. . exported "APEXDEV"."NET1#RDF_DELTA$":"MODEL_0" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RDF_GRANT_INFO$" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RDF_HIST$" 7.328 KB 1 rows
. . exported "APEXDEV"."NET1#RDF_LINK$":"MODEL_0" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RDF_LINK$":"MODEL_1" 12.67 KB 29 rows
. . exported "APEXDEV"."NET1#RDF_MODEL$_TBL" 8.109 KB 1 rows
. . exported "APEXDEV"."NET1#RDF_MODEL_INTERNAL$" 8.093 KB 1 rows
. . exported "APEXDEV"."NET1#RDF_NAMESPACE$" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RDF_NETWORK_INDEX_INTERNAL$" 14.77 KB 12 rows
. . exported "APEXDEV"."NET1#RDF_PARAMETER" 6.492 KB 2 rows
. . exported "APEXDEV"."NET1#RDF_PRECOMP$" 6.828 KB 1 rows
. . exported "APEXDEV"."NET1#RDF_PRECOMP_DEP$" 5.968 KB 3 rows
. . exported "APEXDEV"."NET1#RDF_PRED_STATS$":"MODEL_0" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RDF_PRED_STATS$":"MODEL_1" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RDF_RI_SHAD_2$" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RDF_RULE$" 19.73 KB 20 rows
. . exported "APEXDEV"."NET1#RDF_SYSTEM_EVENT$" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RDF_TERM_STATS$":"MODEL_0" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RDF_TERM_STATS$":"MODEL_1" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RDF_TS$" 0 KB 0 rows
. . exported "APEXDEV"."NET1#RENAMED_APPTAB_RDF_MODEL_ID_1" 0 KB 0 rows
. . exported "APEXDEV"."NET1#SEM_INDEXTYPE_METADATA$" 0 KB 0 rows
Master table "APEXDEV"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for APEXDEV.SYS_EXPORT_SCHEMA_01 is:
/home/oracle/rdf.dmp
Job "APEXDEV"."SYS_EXPORT_SCHEMA_01" successfully completed at Thu Dec 2 14:51:29 2021 elapsed 0 00:00:49
$
-- 入れ替える場合は、すでにあるファイルを削除する。
begin
dbms_cloud.delete_file(
directory_name => 'DATA_PUMP_DIR'
, file_name => 'rdf.dmp');
end;
/
begin
dbms_cloud.get_object(
object_uri => 'https://objectstorage.ap-tokyo-1.oraclecloud.com/p/事前承認済のURL/o/rdf.dmp',
directory_name => 'DATA_PUMP_DIR'
);
end;
Master table "ADMIN"."IMP_APEXDEV" successfully loaded/unloaded
Starting "ADMIN"."IMP_APEXDEV":
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/SEQUENCE/SEQUENCE
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Table "APEXDEV"."NET1#RENAMED_APPTAB_RDF_MODEL_ID_1" exists. All dependent
metadata and data will be skipped due to table_exists_action of skip
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "APEXDEV"."NET1#RDF_LINK$":"MODEL_2" 23.95 KB 219 rows
. . imported "APEXDEV"."NET1#RDF_VALUE$" 23.67 KB 94 rows
*** Job percent done = 32
. . imported "APEXDEV"."NET1#RDF_RULEBASE$" 6.585 KB 9 rows
. . imported "APEXDEV"."NET1#RDF_CLIQUE$":"MODEL_0" 0 KB 0 rows
. . imported "APEXDEV"."NET1#RDF_COLLISION$" 5.070 KB 1 rows
*** Job percent done = 99
. . imported "APEXDEV"."NET1#RDF_CRS_URI$" 293.2 KB 5688 rows
. . imported "APEXDEV"."NET1#RDF_DELTA$":"MODEL_0" 0 KB 0 rows
. . imported "APEXDEV"."NET1#RDF_GRANT_INFO$" 0 KB 0 rows
. . imported "APEXDEV"."NET1#RDF_HIST$" 7.328 KB 1 rows
. . imported "APEXDEV"."NET1#RDF_LINK$":"MODEL_0" 0 KB 0 rows
. . imported "APEXDEV"."NET1#RDF_LINK$":"MODEL_1" 12.67 KB 29 rows
. . imported "APEXDEV"."NET1#RDF_MODEL$_TBL" 8.109 KB 1 rows
. . imported "APEXDEV"."NET1#RDF_MODEL_INTERNAL$" 8.093 KB 1 rows
. . imported "APEXDEV"."NET1#RDF_NAMESPACE$" 0 KB 0 rows
. . imported "APEXDEV"."NET1#RDF_NETWORK_INDEX_INTERNAL$" 14.77 KB 12 rows
. . imported "APEXDEV"."NET1#RDF_PARAMETER" 6.492 KB 2 rows
. . imported "APEXDEV"."NET1#RDF_PRECOMP$" 6.828 KB 1 rows
. . imported "APEXDEV"."NET1#RDF_PRECOMP_DEP$" 5.968 KB 3 rows
. . imported "APEXDEV"."NET1#RDF_PRED_STATS$":"MODEL_0" 0 KB 0 rows
. . imported "APEXDEV"."NET1#RDF_PRED_STATS$":"MODEL_1" 0 KB 0 rows
. . imported "APEXDEV"."NET1#RDF_RI_SHAD_2$" 0 KB 0 rows
. . imported "APEXDEV"."NET1#RDF_RULE$" 19.73 KB 20 rows
. . imported "APEXDEV"."NET1#RDF_SYSTEM_EVENT$" 0 KB 0 rows
. . imported "APEXDEV"."NET1#RDF_TERM_STATS$":"MODEL_0" 0 KB 0 rows
. . imported "APEXDEV"."NET1#RDF_TERM_STATS$":"MODEL_1" 0 KB 0 rows
. . imported "APEXDEV"."NET1#RDF_TS$" 0 KB 0 rows
. . imported "APEXDEV"."NET1#SEM_INDEXTYPE_METADATA$" 0 KB 0 rows
Processing object type SCHEMA_EXPORT/TABLE/GRANT/OWNER_GRANT/OBJECT_GRANT
Processing object type SCHEMA_EXPORT/PROCEDURE/PROCEDURE
ORA-31684: Object type PROCEDURE:"APEXDEV"."NET1#SDO_RDF_PROC_DR_TRUNC_1"
already exists
Processing object type SCHEMA_EXPORT/PROCEDURE/GRANT/OWNER_GRANT/OBJECT_GRANT
Processing object type SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDURE
ORA-39111: Dependent object type
ALTER_PROCEDURE:"APEXDEV"."NET1#SDO_RDF_PROC_DR_TRUNC_1" skipped, base object
type PROCEDURE:"APEXDEV"."NET1#SDO_RDF_PROC_DR_TRUNC_1" already exists
Processing object type SCHEMA_EXPORT/VIEW/VIEW
ORA-31684: Object type VIEW:"APEXDEV"."FAMILY_RDF_DATA" already exists
Processing object type SCHEMA_EXPORT/VIEW/GRANT/OWNER_GRANT/OBJECT_GRANT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/INDEX/FUNCTIONAL_INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type
SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/FUNCTIONAL_INDEX/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Processing object type SCHEMA_EXPORT/VIEW/TRIGGER
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
ORA-39082: Object type TRIGGER:"APEXDEV"."NET1#SDO_RDF_TRIG_AVIEW_1" created
with compilation warnings
*** Job percent done = 100
Job "ADMIN"."IMP_APEXDEV" completed with 4 error(s) at Thu Dec 2 06:54:12 2021
elapsed 0 00:00:25
Job has completed
Final job state = COMPLETED
PL/SQL procedure successfully completed.
Elapsed: 00:00:31.075
APEXアプリケーションの作成
- DataPumpを使ったエクスポート/インポートを行う際に、ローカルのデータベースとAutonomous Databaseでバージョンを合わせていませんでした。ローカルが21c、Autonomous Databaseは19cです。しかし、19cのExpress Editionはリリースされていないので、21cか18cかの選択になります。ライセンスを購入している場合は19cを使うと良いかと思います。MDSYS.SDO_RDFパッケージに含まれるプロシージャに違いがあるようです。
- やはりDataPumpでのデータ移行は強引なので(当然、サポートもされない)、Autonomous Databaseではユーザーがルールベースを追加することはできない前提でRDFナレッジ・グラフを使うのが妥当と言えます。