2025年9月8日月曜日

動物園で飼育されているレッサー・パンダの血統を辿るAPEXアプリケーションを作成する

日本の動物園ではレッサー・パンダが多く飼育されています。そのため、日本に住んでいると珍しい動物に思えないかもしれませんが、野生の生息数は10,000頭未満といわれ、IUCN(国際自然保護連合)レッドリストで「絶滅危惧種(Endangered, EN)」 に分類されています。IUCNのレッサー・パンダ(英語ではRed Panda)のサイトはこちらです。

そんな愛らしいレッサー・パンダですが、愛好家が集まって動物園で飼育されているレッサー・パンダの血統をGitHubに更新しています。以下のサイトになります。

Red Pand Lineage

血統情報はグラフ表現と親和性が高いので、Oracle Database 23aiのデータベースにロードしてProperty Graphとして扱うAPEXアプリを作成してみました。

作成したアプリケーションは以下のように動作します。

ドロップダウン・リスト(アイテム・タイプは1つ選択)、Graph Visualization Plugin、マップ、対話モード・レポートのソースをProperty Graphとしています。


このアプリケーションのエクスポートは以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/red-panda-lineage.zip

以下より、作成したAPEXアプリケーションを紹介します。

最初にレッサー・パンダの血統データをデータベースにロードします。

SQLclでAPEXのワークスペース・スキーマに接続します。

sql wksp_apexdev@localhost/freepdb1

% sql wksp_apexdev@localhost/freepdb1 



SQLcl: 金 9月 05 19:02:19 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


パスワード (**********?) ******

接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.9.0.25.07


SQL> 


Red Panda LineageのGitHubのページDownload the dataset (JSON)というリンクがあります。このリンク先のJSONファイルをJSONコレクション表に保存します。

JSONコレクション表RED_PANDA_LINEAGEを作成します。

create json collection table red_panda_lineage;

SQL> create json collection table red_panda_lineage;


JSON collection table RED_PANDA_LINEAGEは作成されました。


SQL> 


以下のコードを実行し、JSONファイルを表RED_PANDA_LINEAGEに保存します。

SQL> declare

  2      l_response clob;

  3      e_get_json_failed exception;

  4  begin

  5      apex_web_service.set_request_headers('Content-Type','application/json');

  6      l_response := apex_web_service.make_rest_request(

  7          p_url => 'https://wwoast.github.io/redpanda-lineage/export/redpanda.json',

  8          p_http_method => 'GET'

  9      );

 10      if apex_web_service.g_status_code <> 200 then

 11          raise e_get_json_failed;

 12      end if;

 13      delete from red_panda_lineage;

 14      insert into red_panda_lineage values(l_response);

 15      commit;

 16  end;

 17* /


PL/SQLプロシージャが正常に完了しました。


SQL> 


以下のSELECT文を実行し、JSONデータに含まれる頂点の属性を確認します。Oracle Databaseの機能のひとつであるJSONデータガイドを参照します。


SQL> with vt as (

  2      select json_dataguide(v.data, dbms_json.format_flat) as guide

  3      from red_panda_lineage l, json_table(l.data, '$.vertices[*]'

  4          columns data json path '$'

  5      ) v

  6  )

  7  select jt.path, jt.type, jt.length

  8  from vt,

  9      json_table(vt.guide, '$'

 10          columns (

 11              nested path '$[*]'

 12              columns (

 13                  path varchar2(4000) path '$."o:path"',

 14                  type varchar2(209)  path '$.type',

 15                  length number       path '$."o:length"'

 16              )

 17          )

 18      ) jt

 19  where jt.path not like '%photo%' and jt.path not like '%link%'

 20* order by jt.path;


PATH                 TYPE         LENGTH 

____________________ _________ _________ 

$                    object            1 

$."cs.address"       string          128 

$."cs.location"      string           32 

$."cs.name"          string           32 

$."cs.othernames"    string           64 

$."da.address"       string           64 

$."da.location"      string           64 

$."da.name"          string           32 

$."de.address"       string           64 

$."de.location"      string           32 

$."de.name"          string           64 

$."de.othernames"    string           32 

$."en.address"       string          128 

$."en.location"      string           64 

$."en.name"          string           64 

$."en.nicknames"     string          128 


[中略]


$._id                 string           64 

$.birthday            string           16 

$.closed              string           16 

$.commitdate          string           16 

$.death               string           16 

$.flag                string           16 

$.gender              string            8 

$.https               string           64 

$.latitude            string           16 

$.longitude           string           16 

$.map                 string          128 

$.opened              string           16 

$.species             string            1 

$.uncertainty         string          128 

$.uncertainy          string           64 

$.uncertinty          string           32 


PATH         TYPE         LENGTH 

____________ _________ _________ 

$.website    string          128 


124行が選択されました。 


SQL> 


SELECT文で検索される属性のうち、写真やリンクはWHERE句で対象から外しています。それ以外は、名前や住所が言語毎に属性になっています。今回は日本語と英語の情報だけを参照します。

同様にエッジの属性も参照します。

SQL> with vt as (

  2      select json_dataguide(v.data, dbms_json.format_flat) as guide

  3      from red_panda_lineage l, json_table(l.data, '$.edges[*]'

  4          columns data json path '$'

  5      ) v

  6  )

  7  select jt.path, jt.type, jt.length

  8  from vt,

  9      json_table(vt.guide, '$'

 10          columns (

 11              nested path '$[*]'

 12              columns (

 13                  path varchar2(4000) path '$."o:path"',

 14                  type varchar2(209)  path '$.type',

 15                  length number       path '$."o:length"'

 16              )

 17          )

 18      ) jt

 19* order by jt.path;


PATH             TYPE         LENGTH 

________________ _________ _________ 

$                object            1 

$._in            string           32 

$._label         string           16 

$._out           string            4 

$.probability    string            4 


SQL> 


プロパティ・グラフの頂点を保存するマテリアライズド・ビューを、RED_PANDA_VERTICES_PANDAおよびRED_PANDA_VERTICES_ZOOとして作成します。idが0より大きい要素はレッサー・パンダで、idが0より小さい要素は動物園を表しています。

元のJSONファイルのedges要素には、4種類のラベルfamilyzoobirthplacelitterが含まれています。それぞれを分けてエッジとして保存するマテリアライズド・ビューを、RED_PANDA_EDGES_FAMILYRED_PANDA_EDGES_ZOORED_PANDA_EDGES_BIRTHPLACERED_PANDA_EDGES_LITTERとして作成します。

これらのマテリアライズド・ビューを元に、プロパティ・グラフRED_PANDA_GRAPHを作成します。


SQL> create or replace property graph red_panda_graph

  2  vertex tables (

  3      red_panda_vertices_panda key (panda_id)

  4      label red_panda properties are all columns,

  5      red_panda_vertices_zoo   key (zoo_id)

  6      label zoo properties are all columns

  7  )

  8  edge tables (

  9      red_panda_edges_family key (id)

 10      source key (vertex_in) references red_panda_vertices_panda (panda_id)

 11      destination key (vertex_out) references red_panda_vertices_panda (panda_id)

 12      label family

 13      properties are all columns,

 14      red_panda_edges_zoo key (id)

 15      source key (vertex_in) references red_panda_vertices_panda (panda_id)

 16      destination key (vertex_out) references red_panda_vertices_zoo (zoo_id)

 17      label currentzoo

 18      properties are all columns,

 19      red_panda_edges_birthplace key (id)

 20      source key (vertex_in) references red_panda_vertices_panda (panda_id)

 21      destination key (vertex_out) references red_panda_vertices_zoo (zoo_id)

 22      label birthplace

 23      properties are all columns,

 24      red_panda_edges_litter key (id)

 25      source key (vertex_in) references red_panda_vertices_panda (panda_id)

 26      destination key (vertex_out) references red_panda_vertices_panda (panda_id)

 27      label litter

 28      properties are all columns

 29* );


Property GRAPHは作成されました。


SQL> 


以上でプロパティ・グラフRED_PANDA_GRAPHが作成できました。

APEXアプリケーションの説明に移ります。

以下のレッサー・パンダの選択には、ページ・アイテム・タイプの1つ選択を使っています。複数の列を選択リストに表示するため、共有コンポーネントRED PANDASというLOVを作成し、LOVに割り当てています。


共有コンポーネントLOVRED PANDASソースSQL問合せに以下を記述しています。現時点で動物園で飼育されている個体、または、亡くなったときに動物園で飼育されていたレッサー・パンダの個体を一覧しています。


追加表示列にレッサー・パンダの属性を追加して、名前飼育園館場所などで検索できるように、表示可能検索可能はいに切り替えます。


ページ・アイテムP1_RED_PANDAで、血統を辿る起点にするレッサー・パンダを選択します。選択を切り替えたときに、グラフ表示、対話モード・レポート、マップ・リージョンをリフレッシュするよう、動的アクションを作成しています。


血統のグラフ表示に、Graph Visualization Pluginを使用しています。Graph Visualization Pluginのインストールについては、こちらの記事「Graph Visualization Plug-inのサンプル・アプリケーションをOracle Database 23aiのAPEXにインストールする」にて紹介しています。


リージョン血統ソースSQL問合せに以下を記述しています。グラフを表示するために、SELECT文の検索結果はVERTEX_ID()EDGE_ID()VERTEX_ID()の戻り値とします。


グラフの頂点の表示をカスタマイズするために、属性Rule Based StylesBase Stylesを設定します。Styles (Deprecated - use BaseStyles instead)に文字が設定されていると、Base Stylesの設定が無視されます。そのため、この設定は必ず空にします。


グラフに表示されている頂点をクリックしたときに、ページ・アイテムP1_RED_PANDAに設定されているIDを、クリックした頂点のIDに置き換えます。結果として血統を検索する起点が変わります。

Graph Visualization Pluginのリージョンに動的アクションを作成します。タイミングイベントSelection Change[Graph Visualization]です。TRUEアクションとして、以下のJavaScriptを実行します。



対話モード・レポートでは、グラフに表示されているレッサー・パンダの属性情報をレポートとして一覧します。


対話モード・レポートのソースSQL問合せに以下を記述します。一覧に族柄を含めるためONE ROW PER STEPを指定し、マッチ毎に先祖なのか子孫なのかを確認しています。



マップ・リージョンには、グラフに表示されているレッサー・パンダのうち、生存している個体に限定して、それらを飼育している園館を地図上に表示しています。


マップのソースSQL問合せとして、以下を記述しています。



レイヤー飼育場所ツールチップ拡張フォーマットオンに変更し、HTML式として以下を記述します。

動物園: &ZOO_NAME.<br>
場所: &LOCATION.<br>
飼育個体: &PANDA_NAMES.


地図上のポイントにカーソルを合わせるとツール・チップが開き、動物園の名前、位置、それとその動物園で現在飼育しているレッサー・パンダが表示されます。


今回作成したAPEXアプリケーションの説明は以上です。

ひとつのプロパティ・グラフRED_PANDA_GRAPHを、いろいろなAPEXコンポーネントのソースとして使用する例を紹介しました。

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