16.8 PGXでのユーザー定義関数(UDF)
ユーザー定義関数(UDF)を使用すると、PGXのユーザーはPGQL問合せまたはカスタム・グラフ・アルゴリズムにカスタム・ロジックを追加して、組込み関数をカスタム要件で補完できます。
注意:
UDFはPGXサーバーで任意のコードを実行できるようにするため、機密データにアクセスする可能性があります。さらに、いずれのPGXセッションでも、PGXサーバーで有効になっている任意のUDFを呼び出すことができます。UDFを有効にするアプリケーション管理者は、次の点を確認する必要があります。
- すべてのUDFコードが信頼できること。
 - UDFが改ざんできない安全な場所に保管されること。
 
さらに、PGXでは、UDFはステートレスで副次効果がないものとみなされます。
PGXは、次の2種類のUDFをサポートしています。
- Java UDF
 - JavaScript UDF
 
Java UDFの使用方法
次の簡単な例は、PGXサーバーでJava UDFを登録して呼び出す方法を示しています。
- public staticメソッドのあるクラスを作成します。たとえば:
package my.udfs; public class MyUdfs { public static String concat(String a, String b) { return a + b; } } - クラスをコンパイルしてJARファイルに圧縮します。たとえば:
mkdir ./target javac -d ./target *.java cd target jar cvf MyUdfs.jar * - JARファイルを
/opt/oracle/graph/pgx/server/libにコピーします。 - UDF JSON構成ファイルを作成します。たとえば、
/path/to/my/udfs/dir/my_udfs.jsonに次のものが含まれているとします。{ "user_defined_functions": [ { "namespace": "my", "language": "java", "implementation_reference": "my.udfs.MyUdfs", "function_name": "concat", "return_type": "string", "arguments": [ { "name": "a", "type": "string" }, { "name": "b", "type": "string" } ] } ] } /etc/oracle/graph/pgx.confに、UDF構成ファイルが含まれているディレクトリを示します。たとえば:"udf_config_directory": "/path/to/my/udfs/dir/"- PGXサーバーを再起動します。たとえば:
sudo systemctl restart pgx - PGQL問合せ内からUDFの起動を試行します。たとえば:
graph.queryPgql("SELECT my.concat(my.concat(n.firstName, ' '), n.lastName) FROM MATCH (n:Person)") - PGXアルゴリズム内からUDFの起動を試行します。たとえば:
                        
ノート:
使用するUDFごとに、@Udf注釈で注釈を付ける同じスキーマを持つ抽象メソッドを作成する必要があります。import oracle.pgx.algorithm.annotations.Udf; .... @GraphAlgorithm public class MyAlogrithm { public void bomAlgorithm(PgxGraph g, VertexProperty<String> firstName, VertexProperty<String> lastName, @Out VertexProperty<String> fullName) { ... fullName.set(v, concat(firstName.get(v), lastName.get(v))); ... } @Udf(namespace = "my") abstract String concat(String a, String b); } 
JavaScript UDF
JavaScript UDFの要件は次のとおりです。
- JavaScriptソースにはすべての依存関係が含まれている必要があります。
 - ソースには有効なエクスポートが少なくとも1つ含まれている必要があります。
 - UDF構成ファイルで
languageパラメータをjavascriptに設定する必要があります。 
たとえば、次のようなJavaScriptソース・ファイルformat.jsを考えてみます。
                  
//format.js
const fun = function(name, country) {
  if (country == null) return name;
  else return name + " (" + country + ")";
}
module.exports = {stringFormat: fun};
                  format.jsからUDFをロードするには、UDF構成ファイルは次のようになります。
                  
{
  "namespace": "my",
  "function_name": "format",
  "language": "javascript",
  "source_location": "format.js",
  "source_function_name": "stringFormat",
  "return_type": "string",
  "arguments": [
    {
      "name": "name",
      "type": "string"
    },
    {
      "name": "country",
      "type": "string"
    }
  ]
}
                  ノート:
この場合、UDFの名前と実装方法が異なるため、source_function_nameフィールドにUDFの名前を設定する必要があります。また、source_locationフィールドにソース・コード・ファイルのパスを指定することもできます。
                  UDF構成ファイル情報
 UDF構成ファイルは、user_defined_functionsの配列を含むJSONファイルです。(このようなファイルの例は、前述のJava UDFの使用方法サブセクションの「UDF JSON構成ファイルの作成」のステップを参照してください)。
                  
各ユーザー定義関数は、次の表に示すフィールドをサポートしています。
表16-11 各UDFのフィールド
| フィールド | データ型 | 説明 | 必須かどうか | 
|---|---|---|---|
| function_name | string | PGXで識別子として使用される関数の名前 | 必須 | 
| language | enum[java, javascript] | 関数のソース言語(javaまたはjavascript)
                               | 
                              必須 | 
| return_type | enum[boolean, integer, long, float, double, string] | 関数の戻り型 | 必須 | 
| arguments | オブジェクトの配列 | 引数の配列。引数ごとに、型、引数名、必須かどうか | [] | 
| implementation_reference | string | クラスパス上の関数名への参照 | null | 
| namespace | string | PGXでの関数のネームスペース | null | 
| source_code | string | インラインで提供される関数のソース・コード | null | 
| source_function_name | string | ソース言語での関数の名前 | null | 
| source_location | string | 関数のソース・コードへのローカル・ファイル・パス | null | 
構成されたすべてのUDFは、次に示すフィールドの組合せに関して一意である必要があります。
- namespace
 - function_name
 - arguments
 
親トピック: グラフ分析を使用したアプリケーションの開発