2022年9月6日火曜日

Autonomous DatabaseでのSEM_MATCH関数の動作を確認する

 Autonomous Databaseでデータベース組み込みのJavaVMが使えるようになりました。今まではSEM_MATCH関数を使うことができなかったので、JavaVMを有効にして動作を確認してみます。

確認作業として、以前の記事「Oracle APEXよりGraphの機能を呼び出してみる」に記載している作業をやり直してみます。以下の一連のコマンドを実行します。

/*
* APEXのワークスペースがAPEXDEV、スキーマがWKSP_APEXDEVとして
* 作成されていることが前提。
*
* ネットワーク NET1 を作成する。
*/
begin
sem_apis.create_sem_network(
tablespace_name => 'DATA'
, network_owner => sys_context('USERENV','current_schema')
, network_name => 'NET1'
);
end;
/
/*
* モデル M1 を作成する。
*/
begin
sem_apis.create_sem_model(
model_name => 'M1'
, table_name => null
, column_name => null
, network_owner => sys_context('USERENV','current_schema')
, network_name => 'NET1'
);
end;
/
/*
* 作成したモデルを確認するSELECT文。
*/
select * from net1#sem_model$;
/*
* データを1行挿入する。
*/
insert into net1#rdft_m1(triple) values(sdo_rdf_triple_s('M1','<urn:person1>','<urn:name>','"Peter"',sys_context('USERENV','current_schema'),'NET1'));
/*
* SEM_MATCHを使った検索を行なう。
*/
select s$rdfterm, p$rdfterm, o$rdfterm
from table(sem_match(
query => 'SELECT ?s ?p ?o WHERE { ?s ?p ?o }'
, models => SEM_MODELS('M1')
, rulebases => null
, aliases => null
, filter => null
, index_status => null
, options =>' PLUS_RDFT=VC '
, graphs => null
, named_graphs => null
, network_owner => 'WKSP_APEXDEV'
, network_name => 'NET1'
));
/*
* SPARQL_TO_SQLの呼び出し。
*/
declare
sparql_stmt clob;
sql_stmt clob;
begin
sparql_stmt := 'SELECT ?s ?p ?o WHERE { ?s ?p ?o }';
sql_stmt :=
sem_apis.sparql_to_sql(
sparql_query => sparql_stmt
, models => sem_models('M1')
, rulebases => null
, aliases => null
, index_status => null
, options => ' PLUS_RDFT=VC '
, graphs => null
, named_graphs => null
, network_owner => sys_context('USERENV','current_schema')
, network_name => 'NET1'
);
dbms_output.put_line(sql_stmt);
end;
/

最初にネットワークNET1を作成します。

次にモデルM1を作成します。

作成したモデルM1を確認します。


データを1行挿入します。


SEM_MATCH関数を含んだ問合せを発行します。Autonomous DatabaseではJavaVMが使えないためエラーが発生します。

ORA-13199: JAVAVM is not installed

※) SEM_MATCH関数の引数network_ownerとしてsys_context('USERENV','current_schema')を指定すると以下のエラーが発生するため、APEXのワークスペース・スキーマ名を直接指定します。

ORA-20000: Unable to read model M1 info from "MDSYS".rdf_model$ ORA-00942: 表またはビューが存在しません。


Autonomous DatabaseのJavaVMを有効にします。マニュアルの以下の記載に従います。

BEGIN
   DBMS_CLOUD_ADMIN.ENABLE_FEATURE(
       feature_name => 'JAVAVM' );
END;
/
データベース・アクションにユーザーADMINで接続して、上記のSQLを実行します。JAVAVMを有効化した後、Autonomous Databaseの再起動を行います。


マニュアルのNotes for Oracle Java on Autonomous Databaseに、一旦JAVAVMを有効化すると無効にはできない、また、メンテナンス時にはJavaの機能が使えなくなる、との注意書きがあります。

During the maintenance window, during the Java patching phase there would be no response for Java session calls or you would see an ORA-29548 error. After the maintenance window completes, Java usage is restored.

JavaVMを使うとAutonomous Databaseの可用性は低くなるため、必要なときに限り(例えば今回のようにSEM_MATCH関数を使いたいなど)JAVAVMを有効化するのが良いでしょう。

JavaVMを有効化した後、再度SEM_MATCH関数を含んだ問合せを発行します。

今度は検索結果が返されます。SEM_MATCH関数が使えるようになりました。


SEM_APIS.SPARQL_TO_SQLも実行してみます。こちらも結果が返ってきます。


以前の記事で作成したAPEXアプリケーションRDF Graphも変更します。

ページ・デザイナページ番号1の対話モード・レポートのページを開きます。

ページ・アイテムP1_SPARQLとして、SPARQLの問合せ文を入力するテキスト・フィールドを作成します。


対話モード・レポートのソースタイプSQL問合せを返すファンクション本体に変更し、ファンクション本体として以下を記述します。

declare
sparql_stmt clob;
sql_stmt clob;
begin
/*
* ソースが評価されるときはP1_SPARQLはNULLなので、エラーになる。
* それを避けるために、NULLのときのデフォルトのSPARQLを指定する。
*/
if :P1_SPARQL is null then
sparql_stmt := 'SELECT ?s ?p ?o WHERE { ?s ?p ?o }';
else
sparql_stmt := :P1_SPARQL; -- 実行時に使用される。
end if;
sql_stmt :=
sem_apis.sparql_to_sql(
sparql_query => sparql_stmt
, models => sem_models('M1')
, rulebases => null
, aliases => null
, index_status => null
, options => ' PLUS_RDFT=VC '
, graphs => null
, named_graphs => null
, network_owner => sys_context('USERENV','current_schema')
, network_name => 'NET1'
);
return sql_stmt;
end;

SEM_MATCH関数の引数queryにバインド変数を割り当てることができなかったため(およびnvlやcoalesce関数でバインド変数がNULLのときに固定したSPARQL文を割り当てることができなかった)、SEM_APIS.SPARQL_TO_SQLを代わりに使用しています。

送信するページ・アイテムとしてP1_SPARQLを指定します。


ページ・アイテムP1_SPARQLに入力したSPARQL問合せを実行するボタンを作成します。

識別ボタン名B_SUBMITラベル送信とします。レイアウトリージョンとしてRDF Graph位置としてNextを選択します。ブレッドカラムの右端にボタンが配置されます。動作アクションは、デフォルトのページの送信から変更しません。


以上で完成です。対話モード・レポートのソースが評価される際に、SPARQLとして以下を与えています。

SELECT ?s ?p ?o WHERE { ?s ?p ?o }

そのため、レポート列として?s ?p ?o(主語、述語、目的語)に関連する列が認識されています。P1_SPARQLとして与えるSPARQLの問合せ文の検索結果を?s ?p ?oから変更すると、認識済みの列と一致しなくなります。そのため変更できるのは検索条件のみになります。


今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/rdf-graph.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。