2026年6月24日水曜日

Oracle AI Database 26ai 23.26.2でサポートされたグラフ・アルゴリズム・ファンクションを実行する

Oracle AI Database 26ai 23.26.2にてパッケージDBMS_OGAにより、いくつかのグラフ・アルゴリズムがサポートされました。

Property Graph: In-Database Graph Algorithms

Property Graph: In-Database Graph Algorithms

Developers can use the Oracle Graph Algorithms package (DBMS_OGA) to execute popular algorithms like PageRank on graphs in the database.

Developers can now execute graph algorithms using SQL and PL/SQL. They can build graph applications using SQL development tools and frameworks.


ドキュメントのGraph Developer's Guide for Property Graph(Release 26.2)の7.3
Graph Algorithm Functions Supported by DBMS_OGA
から、以下のアルゴリズムがサポートされたことが確認できます。

BELLMAN-FORD
PAGERANK
PERSONALIZED_PAGERANK
PERSONALIZED_PAGERANK_SET
WCC

ローカルのコンテナで実行できるOracle AI Database 26ai Freeが23.26.2に置き換えられたので、これらのグラフ・アルゴリズム・ファンクションを実行してみます。

公式ドキュメントの例に記載されているSELECT文を実行します。これらの例を実行するには、Property Graphのサンプル・データセットbank_graphを、事前にデータベースにインストールする必要があります。

Bank Graph DatasetはGitHubの以下から取得します。


作業ディレクトリとしてbank_graphを作成し、移動します。

mkdir bank_graph
cd bank_graph


Documents % mkdir bank_graph

Documents % cd bank_graph

bank_graph % 


data/BANK_ACCOUNTS.csvおよびdata/BANK_TRANSFERS.csvを手元にダウンロードします。

curl -OL https://raw.githubusercontent.com/oracle-samples/oracle-graph/refs/heads/master/shared/datasets/bank_graph/data/BANK_ACCOUNTS.csv
curl -OL https://raw.githubusercontent.com/oracle-samples/oracle-graph/refs/heads/master/shared/datasets/bank_graph/data/BANK_TRANSFERS.csv

bank_graph % curl -OL https://raw.githubusercontent.com/oracle-samples/oracle-graph/refs/heads/master/shared/datasets/bank_graph/data/BANK_ACCOUNTS.csv

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

100 27756  100 27756    0     0   493k      0 --:--:-- --:--:-- --:--:--  501k

bank_graph % curl -OL https://raw.githubusercontent.com/oracle-samples/oracle-graph/refs/heads/master/shared/datasets/bank_graph/data/BANK_TRANSFERS.csv

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

100  129k  100  129k    0     0   479k      0 --:--:-- --:--:-- --:--:--  480k

bank_graph % ls

BANK_ACCOUNTS.csv BANK_TRANSFERS.csv

bank_graph % 


公式では、setup/oracle-graph-26ai-sqldeveloper.sqlとしてセットアップ用のスクリプトが提供されています。グラフ・アルゴリズム・ファンクションの例とラベルの設定が整合していなかったので、セットアップ用のスクリプトを書き直しました。

以下のスクリプトをダウンロードし、ローカルで実行しているOracle AI Databaseのスキーマに接続して実行します。接続先のスキーマへの権限の割り当てについては、7.2 Privileges to Run a Graph Algorithm Functionを参照してください。

表BANK_ACCOUNTSおよびBANK_TRANSFERSへのCSVデータのロードも、スクリプト内で実行しています。

@oracle-graph-setup

SQL> @oracle-graph-setup


Property GRAPHが削除されました。



Table BANK_TRANSFERSが削除されました。



Table BANK_ACCOUNTSが削除されました。



Table BANK_ACCOUNTSは作成されました。



Table BANK_TRANSFERSは作成されました。



Table BANK_ACCOUNTSが変更されました。



Table BANK_TRANSFERSが変更されました。



Table BANK_TRANSFERSが変更されました。



Table BANK_TRANSFERSが変更されました。



csv

column_names on

delimiter ,

enclosures ""

double

encoding UTF8

row_limit off

row_terminator default

skip_rows 0

skip_after_names


データを表にロードします APEXDEV.BANK_ACCOUNTS


#INFO 処理された行数: 1,000

#INFO エラーのある行数: 0

#INFO 最後にコミットされたバッチで処理された最後の行: 1,000

成功: エラーなしで処理されました


csv

column_names on

delimiter ,

enclosures ""

double

encoding UTF8

row_limit off

row_terminator default

skip_rows 0

skip_after_names


データを表にロードします APEXDEV.BANK_TRANSFERS


#INFO 処理された行数: 5,001

#INFO エラーのある行数: 0

#INFO 最後にコミットされたバッチで処理された最後の行: 5,001

成功: エラーなしで処理されました


Property GRAPHは作成されました。



GRAPH_NAME    GRAPH_MODE    ALLOWS_MIXED_TYPES    INMEMORY    

_____________ _____________ _____________________ ___________ 

BANK_GRAPH    TRUSTED       NO                    NO          



DBMS_METADATA.GET_DDL('PROPERTY_GRAPH','BANK_GRAPH')    

_______________________________________________________ 

                                                        

  CREATE PROPERTY GRAPH "APEXDEV"."BANK_GRAPH"          

  VERTEX TABLES (                                       

   "APEXDEV".                                           



GRAPH_NAME    ELEMENT_NAME      ELEMENT_KIND    OBJECT_OWNER    OBJECT_NAME       

_____________ _________________ _______________ _______________ _________________ 

BANK_GRAPH    BANK_ACCOUNTS     VERTEX          APEXDEV         BANK_ACCOUNTS     

BANK_GRAPH    BANK_TRANSFERS    EDGE            APEXDEV         BANK_TRANSFERS    



GRAPH_NAME    LABEL_NAME    PROPERTY_NAME    DATA_TYPE       DATA_LENGTH    DATA_PRECISION    DATA_SCALE    DATA_CHAR_LENGTH CHARACTER_SET_NAME    COLLATION            PROPERTY_ORDER 

_____________ _____________ ________________ ____________ ______________ _________________ _____________ ___________________ _____________________ _________________ _________________ 

BANK_GRAPH    ACCOUNTS      ID               NUMBER                   22                                                   0                                                         1 

BANK_GRAPH    ACCOUNTS      NAME             VARCHAR2                400                                                 400 CHAR_CS               USING_NLS_COMP                    2 

BANK_GRAPH    ACCOUNTS      BALANCE          NUMBER                   22                20             2                   0                                                         3 

BANK_GRAPH    TRANSFERS     SRC_ACCT_ID      NUMBER                   22                                                   0                                                         1 

BANK_GRAPH    TRANSFERS     DST_ACCT_ID      NUMBER                   22                                                   0                                                         2 

BANK_GRAPH    TRANSFERS     AMOUNT           NUMBER                   22                                                   0                                                         3 


6行が選択されました。 



   ACCT_ID    NUM_TRANSFERS 

__________ ________________ 

       387               39 

       934               39 

       135               36 

       534               32 

       380               31 

       330               30 

       746               28 

       406               28 

       920               26 

       352               26 


10行が選択されました。 



   ACCT_ID    NUM_IN_MIDDLE 

__________ ________________ 

       387              195 

       934              195 

       135              180 

       534              160 


[中略]


10行が選択されました。 



   ACCOUNT_ID    NUM_CYCLES 

_____________ _____________ 

          135            37 

          387            34 

          934            30 

          640            28 

          458            27 

           13            27 

          559            25 

          352            23 

          406            23 

          499            22 


10行が選択されました。 


SQL> 


セットアップ・スクリプトに含まれているSELECT文が結果を返していれば、プロパティ・グラフのサンプル・データセットのインストールは完了です。

BELLMAN-FORDのサンプルを実行します。
select *
from graph_table(
  dbms_oga.bellman_ford(
    bank_graph,
    json {
      'GRAPH_OWNER' : sys_context('USERENV','CURRENT_SCHEMA'),
      'GRAPH_NAME'  : 'BANK_GRAPH',
      'ELEM_TABLE'  : 'BANK_ACCOUNTS',
      'KEY_VALUE'   : json { 'ID' : 101 }
    },
    property(edge input amount default on null 0),
    property(vertex output cost)
  )
  match (a is accounts)
  columns (a.id, a.cost)
)
order by cost asc
fetch first 5 rows only;

SQL> select *

  2  from graph_table(

  3    dbms_oga.bellman_ford(

  4      bank_graph,

  5      json {

  6        'GRAPH_OWNER' : sys_context('USERENV','CURRENT_SCHEMA'),

  7        'GRAPH_NAME'  : 'BANK_GRAPH',

  8        'ELEM_TABLE'  : 'BANK_ACCOUNTS',

  9        'KEY_VALUE'   : json { 'ID' : 101 }

 10      },

 11      property(edge input amount default on null 0),

 12      property(vertex output cost)

 13    )

 14    match (a is accounts)

 15    columns (a.id, a.cost)

 16  )

 17  order by cost asc

 18* fetch first 5 rows only;


    ID COST      

______ _________ 

   101 0.0       

   418 1751.0    

   207 3065.0    

   261 3888.0    

   794 5046.0    


SQL> 


PAGERANKのサンプルを実行します。
select id, rank
from graph_table(
  dbms_oga.pagerank(
    bank_graph,
    property(vertex output rank),
    10, 1.0, 0.85d, false
  )
  match (a is accounts)
  columns (a.id, a.rank)
)
order by rank desc
fetch first 5 rows only;

SQL> select id, rank

  2  from graph_table(

  3    dbms_oga.pagerank(

  4      bank_graph,

  5      property(vertex output rank),

  6      10, 1.0, 0.85d, false

  7    )

  8    match (a is accounts)

  9    columns (a.id, a.rank)

 10  )

 11  order by rank desc

 12* fetch first 5 rows only;


    ID RANK                    

______ _______________________ 

   387 0.006779999999999995    

   934 0.006779999999999995    

   135 0.006269999999999996    

   534 0.005589999999999997    

   380 0.005419999999999998    


SQL> 


PERSONALIZED_PAGERANKのサンプルを実行します。
select *
from graph_table (
  dbms_oga.personalized_pagerank(
    bank_graph,
    property(vertex output rank),
    json {
      'GRAPH_OWNER' : sys_context('USERENV','CURRENT_SCHEMA'),
      'GRAPH_NAME'  : 'BANK_GRAPH',
      'ELEM_TABLE'  : 'BANK_ACCOUNTS',
      'KEY_VALUE'   : json { 'ID' : 200 }
    },
    50, 0.5, 0.85d, false
  )
  match (a is accounts)
  columns (a.id, a.rank)
)
order by rank desc
fetch first 5 rows only;

SQL> select *

  2  from graph_table (

  3    dbms_oga.personalized_pagerank(

  4      bank_graph,

  5      property(vertex output rank),

  6      json {

  7        'GRAPH_OWNER' : sys_context('USERENV','CURRENT_SCHEMA'),

  8        'GRAPH_NAME'  : 'BANK_GRAPH',

  9        'ELEM_TABLE'  : 'BANK_ACCOUNTS',

 10        'KEY_VALUE'   : json { 'ID' : 200 }

 11      },

 12      50, 0.5, 0.85d, false

 13    )

 14    match (a is accounts)

 15    columns (a.id, a.rank)

 16  )

 17  order by rank desc

 18* fetch first 5 rows only;


    ID RANK                   

______ ______________________ 

   200 0.15056794280000008    

   872 0.0318331171           

   439 0.0290869813           

   264 0.0274480045           

   851 0.0267444629           


SQL> 


PERSONALIZED_PAGERANK_SETのサンプルを実行します。
select json_arrayagg(p_json)
from graph_table(
  bank_graph
  match (a is accounts)
  where a.id in (100, 200, 300)
  columns (vertex_id(a) as p_json)
);

SQL> select json_arrayagg(p_json)

  2  from graph_table(

  3    bank_graph

  4    match (a is accounts)

  5    where a.id in (100, 200, 300)

  6    columns (vertex_id(a) as p_json)

  7* );


JSON_ARRAYAGG(P_JSON)                                                                                                                                                                                                                                                                                                        

____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ 

[{"GRAPH_OWNER":"APEXDEV","GRAPH_NAME":"BANK_GRAPH","ELEM_TABLE":"BANK_ACCOUNTS","KEY_VALUE":{"ID":100}},{"GRAPH_OWNER":"APEXDEV","GRAPH_NAME":"BANK_GRAPH","ELEM_TABLE":"BANK_ACCOUNTS","KEY_VALUE":{"ID":200}},{"GRAPH_OWNER":"APEXDEV","GRAPH_NAME":"BANK_GRAPH","ELEM_TABLE":"BANK_ACCOUNTS","KEY_VALUE":{"ID":300}}]    


SQL> 


出力は環境ごとに異なります。PERSONALIZED_PAGERANK_SETの例のJSONファンクションの引数は、上記の出力に置き換えます。
with
  function get_start_vertices return json
  is
    l_arr json;
  begin
    select json_arrayagg(p_json returning json)
      into l_arr
      from graph_table(
        bank_graph
        match (a is accounts)
        where a.id in (100, 200, 300)
        columns (vertex_id(a) as p_json)
      );
    return l_arr;
  end;
select *
from graph_table (
  dbms_oga.personalized_pagerank_set(
    bank_graph,
    property(vertex output rank),
    get_start_vertices(),
    50, 0.5, 0.85d, false
  )
  match (a is accounts)
  columns (a.id, a.rank)
)
order by rank desc
fetch first 5 rows only;
/

SQL> with

  2    function get_start_vertices return json

  3    is

  4      l_arr json;

  5    begin

  6      select json_arrayagg(p_json returning json)

  7        into l_arr

  8        from graph_table(

  9          bank_graph

 10          match (a is accounts)

 11          where a.id in (100, 200, 300)

 12          columns (vertex_id(a) as p_json)

 13        );

 14      return l_arr;

 15    end;

 16  select *

 17  from graph_table (

 18    dbms_oga.personalized_pagerank_set(

 19      bank_graph,

 20      property(vertex output rank),

 21      get_start_vertices(),

 22      50, 0.5, 0.85d, false

 23    )

 24    match (a is accounts)

 25    columns (a.id, a.rank)

 26  )

 27  order by rank desc

 28  fetch first 5 rows only;

 29* /


    ID RANK                    

______ _______________________ 

   200 0.05056237473333334     

   100 0.05                    

   300 0.05                    

   559 0.013113229933333331    

   439 0.010976970833333334    


SQL> 


WCCのサンプルを実行します。
select id, comp_id
from graph_table (
  dbms_oga.wcc (
    bank_graph,
    property(vertex output comp_id))
  match (a is accounts)
  columns (a.id, a.comp_id)
) fetch first 5 rows only;

SQL> select id, comp_id

  2  from graph_table (

  3    dbms_oga.wcc (

  4      bank_graph,

  5      property(vertex output comp_id))

  6    match (a is accounts)

  7    columns (a.id, a.comp_id)

  8* ) fetch first 5 rows only;


    ID    COMP_ID 

______ __________ 

   463          1 

   464          1 

   465          1 

   466          1 

   467          1 


SQL> 


以上でパッケージDBMS_OGAに実装されたグラフ・アルゴリズム・ファンクションが呼び出せることが確認できました。

これらのファンクションを活用してどのようなAPEXアプリケーションが作れるかを、これから考えようと思います。

今回の記事は以上になります。