4.15 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を登録して呼び出す方法を示しています。

  1. public staticメソッドのあるクラスを作成します。次に例を示します。
    package my.udfs;
     
    public class MyUdfs {
      public static String concat(String a, String b) {
        return a + b;
      }
    }
    
  2. クラスをコンパイルしてJARファイルに圧縮します。次に例を示します。
    mkdir ./target
    javac -d ./target *.java
    cd target
    jar cvf MyUdfs.jar *
    
  3. JARファイルを/opt/oracle/graph/pgx/server/libにコピーします。
  4. 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"
             }
           ]
        }
      ]
    }
  5. /etc/oracle/graph/pgx.confに、UDF構成ファイルが含まれているディレクトリを示します。次に例を示します。
    "udf_config_directory": "/path/to/my/udfs/dir/"
  6. PGXサーバーを再起動します。次に例を示します。
    sudo systemctl restart pgx
  7. PGQL問合せ内からUDFの起動を試行します。次に例を示します。
    graph.queryPgql("SELECT my.concat(my.concat(n.firstName, ' '), n.lastName) FROM MATCH (n:Person)")
  8. 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構成ファイルの作成」のステップを参照してください)。

各ユーザー定義関数は、次の表に示すフィールドをサポートしています。

表4-7 各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