Hologres V3.1 以降では、関数計算でユーザー定義関数(UDF)をリモートで呼び出して、複雑なビジネスロジックを処理したり、高度なデータ操作を実行したりできます。このトピックでは、Hologres で UDF を使用する方法について説明します。
概要
リモート関数機能を使用すると、開発者は外部関数を Hologres に統合することで、データ処理および分析機能を拡張できます。 Hologres V3.1 では、リモート関数は Alibaba Cloud 関数計算の呼び出しをサポートしています。この機能により、Alibaba Cloud 関数計算を動的に呼び出して、複雑なビジネスロジックを処理したり、Hologres データをクエリしながら高度なデータ操作を実行したりできます。
リモート関数を使用すると、次の 3 つのシナリオを実装できます。
リアルタイムデータ処理:データをクエリするときに、外部関数を動的に呼び出して、データクレンジング、フォーマット変換、または複雑な計算を実行します。
サードパーティサービス統合:関数計算を使用して、Hologres データと他の Alibaba Cloud サービスまたはサードパーティ API との相互作用を有効にします。
高度な分析:関数計算を使用して、モデル推論や機械学習などの高度な分析アルゴリズムを実装し、結果を Hologres に直接書き戻します。
前提条件
V3.1 以降の Hologres インスタンスが購入されていること。詳細については、「Hologres インスタンスを購入する」をご参照ください。
関数計算 V3.0 がアクティブになっていること。関数計算コンソール にログインして操作を実行できます。
サービスリンクロール
AliyunServiceRoleForHologresRemoteUDFが作成されていること。Hologres コンソール にログインし、左側のナビゲーションウィンドウで [サービスリンクロールの作成] をクリックします。
AliyunServiceRoleForHologresRemoteUDFを選択し、[今すぐ承認] をクリックして承認を完了します。
Hologres インスタンスと関数計算サービスは同じリージョンにある必要があります。
Alibaba Cloud 関数計算をアクティブにし、Hologres が呼び出すための関数を開発およびデプロイする必要があります。詳細については、「コード開発」をご参照ください。
注意事項
スカラー UDF とユーザー定義テーブル値関数(UDTF)のみがサポートされています。ユーザー定義集計関数(UDAF)はサポートされていません。
以下のデータ型とそれに対応する配列型のみがサポートされています:
BOOLEAN、INTEGER、BIGINT、REAL、DOUBLE PRECISION、およびTEXT。リモート関数は定数入力パラメーターをサポートしていません。
この機能は関数計算で料金が発生します。詳細については、「請求」をご参照ください。
この機能は Hologres で追加料金は発生しません。
UDF の管理
拡張機能の作成
この機能を初めて使用する前に、次のステートメントを実行して拡張機能を作成する必要があります。
CREATE EXTENSION [ IF NOT EXISTS ] function_compute;関数の作成
構文
CREATE [ OR REPLACE ] FUNCTION <function_name>
( [ [ argmode ] [ argname ] <argtype> [ { DEFAULT | = } default_expr ] [, ...] ] )
[ RETURNS [SETOF] rettype | RETURNS TABLE ( column_name column_type) ]
LANGUAGE function_compute
AS '<fc_endpoint>/<func_name>'
{
{ CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
| SET function_compute.qualifier TO <qualifier>
| SET function_compute.compression TO <compression>
| SET function_compute.max_batch_size TO <max_batch_size>
} ...パラメーター
パラメーターカテゴリ | パラメーター | 必須 | 説明 |
関数名 | function_name | はい | 関数の名前。
|
関数パラメーター | argtype | はい | パラメーターのデータ型。 |
argmode | いいえ | IN、OUT、および INOUT をサポートします。デフォルト値は IN です。あいまいさを避けるため、INOUT は使用しないことをお勧めします。また、OUT パラメーターまたは INOUT パラメーターは 1 つだけ含めることができます。 | |
argname | いいえ | パラメーター名。
| |
default_expr | いいえ | デフォルト値。入力パラメーターの場合のみ。パラメーターにデフォルト値を指定した場合、後続のすべてのパラメーターにもデフォルト値を指定する必要があります。 | |
関数計算エンドポイント | LANGUAGE function_compute | はい | 固定値。関数計算の使用を宣言します。 |
fc_endpoint | はい | 関数計算の内部エンドポイント。詳細については、「エンドポイント」をご参照ください。 | |
func_name | はい | ターゲット関数名。(関数は事前に関数計算コンソールで作成する必要があります)。 | |
戻り値の型 | rettype | いいえ | 戻り値の型。 OUT パラメーターまたは INOUT パラメーターが存在する場合、RETURNS 句は省略できます。この句が存在する場合、出力パラメーターによって暗示される結果タイプと一致する必要があります。 |
column_name | いいえ | RETURNS TABLE 構文での出力列の名前。 これは、名前付き OUT パラメーターを宣言する別の方法です。違いは、RETURNS TABLE も RETURNS SETOF(セットを返す)を意味することです。 | |
column_type | いいえ | RETURNS TABLE 構文での出力列のデータ型。 | |
NULL 処理戦略 | CALLED ON NULL INPUT | いいえ | デフォルトの動作。NULL は入力に含めることができ、関数は NULL 値ロジックを処理する必要があります。 |
RETURNS NULL ON NULL INPUT | いいえ | 入力が NULL の場合、NULL が直接返されます。 | |
STRICT | いいえ | RETURNS NULL ON NULL INPUT のエイリアス。 | |
関数バージョン管理 | qualifier | いいえ | 呼び出す関数バージョンまたはエイリアスを指定します。デフォルト値は |
リクエスト圧縮アルゴリズム | compression | いいえ | 関数が呼び出されたときにリクエストとレスポンスで使用される圧縮アルゴリズムを指定します。有効な値:
|
リクエストあたりの最大バッチサイズ | max_batch_size | いいえ | バッチごとに関数計算に送信される行の最大数を指定します。 主な目的は、メモリ制限またはその他の制約がある関数計算関数のバッチ処理の行数に上限を設定することです。このパラメーターを明示的に指定しない場合、Hologres は最適なバッチサイズを自動的に計算して使用します。通常、手動による介入は必要ありません。 |
例
スカラー UDF を作成します。
CREATE OR REPLACE FUNCTION rf_add ( a INTEGER, b INTEGER DEFAULT 1 ) RETURNS BIGINT LANGUAGE function_compute AS 'xxxxxxxxxxxxx.cn-shanghai-internal.fc.aliyuncs.com/add' ;UDTF を作成します。
-- 形式 1 CREATE OR REPLACE FUNCTION rf_unnest(TEXT []) RETURNS TABLE (item TEXT ) LANGUAGE function_compute AS 'xxxxxxxxxxxxxx.cn-hangzhou-internal.fc.aliyuncs.com/unnest' STRICT SET function_compute.max_batch_size TO 1024; -- 形式 2 CREATE OR REPLACE FUNCTION rf_unnest(TEXT []) RETURNS SETOF TEXT LANGUAGE function_compute AS 'xxxxxxxxxxxxxx.cn-hangzhou-internal.fc.aliyuncs.com/unnest' STRICT SET function_compute.max_batch_size TO 1024;
関数の表示
作成されたリモート関数を表示します。
SELECT
CASE
WHEN p.proretset = 'f' THEN 'スカラー UDF'
WHEN p.proretset = 't' THEN 'UDTF'
END AS function_type,
n.nspname AS schema_name,
p.proname AS function_name,
pg_get_function_arguments(p.oid) AS arguments,
pg_get_function_result(p.oid) AS return_type,
p.proisstrict AS is_strict,
p.proconfig AS config,
pg_get_functiondef(p.oid) AS definition
FROM
pg_proc p
JOIN pg_language l ON p.prolang = l.oid
JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE
l.lanname = 'function_compute'
AND p.prokind != 'p'
ORDER BY
function_type,
schema_name,
function_name;関数の削除
構文
DROP FUNCTION [ IF EXISTS ] <function_name> [ ( [ [ argmode ] [ argname ] <argtype> [, ...] ] ) ] [, ...]パラメーター
パラメーター | 必須 | 説明 |
function_name | はい | 削除する関数の名前。 |
argtype | はい | パラメーターのデータ型。 |
argmode | いいえ | IN、OUT、および INOUT をサポートします。デフォルトは IN です。あいまいさを避けるため、INOUT は使用しないことをお勧めします。また、OUT パラメーターまたは INOUT パラメーターは 1 つだけ含めることができます。 |
argname | いいえ | パラメーター名。入力パラメーターの場合、ドキュメントの目的でのみ使用されます。出力パラメーターの場合、返される結果セットの列名を決定します。省略した場合、システムはデフォルト名を生成します。 |
例
DROP FUNCTION rf_add(INTEGER, INTEGER);データ相互作用形式
Hologres から関数計算へのリクエスト形式
Hologres は、POST を介して関数計算の InvokeFunction インターフェースを呼び出します。リクエスト本文は JSON 形式で、最上位レベルはオブジェクトです。現在、data という名前のキーのみが含まれており、その値は 2 次元配列です。配列の各要素はバッチ内のデータの行に対応し、関数を呼び出すために必要なパラメーターが含まれています。
データシリアル化ルール
BOOLEANは JSON BOOLEAN 型としてシリアル化されます。INTEGERおよびBIGINTは JSON NUMBER 型としてシリアル化されます。REALおよびDOUBLE PRECISIONは JSON NUMBER 型としてシリアル化されます。TEXTは JSON STRING 型としてシリアル化されます。NULLは JSONNULLとしてシリアル化されます。
例
以下は、シグネチャ rf_demo(TEXT, INTEGER, BOOLEAN) を持つリモート関数のシリアル化されたリクエストの例です。
{
"data": [
["foo", 100, true],
[null, null, false],
["bar", 200, false]
]
} 関数計算から Hologres へのレスポンス形式
関数計算がバッチデータの処理を完了すると、次の仕様に従って JSON 形式で結果データを Hologres に返す必要があります。
スカラー関数
最上位レベルには
resultsフィールドが含まれている必要があり、その値は配列で、各要素は入力データの結果の行に対応します。結果の各行は配列である必要があり、入力データの順序に厳密に従います。具体的には、N 番目の要素は入力データの N 番目の行に対応する必要があります。
以下は、サイズ 4 のバッチの戻りデータの例です。
{ "results": [ ["Beijing"], ["Shanghai"], ["Shenzhen"], ["Guangzhou"] ] }UDTF:UDTF は、1 行の入力から複数の行の出力を生成することをサポートしており、元の入力行との関連付けを識別するために行番号(row_num)が必要です。
最上位レベルには
resultsフィールドが含まれている必要があり、その値は配列で、各要素は出力データの行に対応します。結果の各行は、2 つの要素を含む配列である必要があります。
row_num(最初の要素):元の入力データの行番号(0 ベースのインデックス)。入力と出力を関連付けるために使用されます。 row_num は順不同にすることはできず、昇順で返す必要があります。
result(2 番目の要素):処理後の戻り値の行。
次のサンプルコードは例を示しています。
{ "results": [ [0, "Beijing"], [1, "Shanghai"], [3, "Shenzhen"], [3, "Guangzhou"], ] }
UDF の例
この例では、unnest 関数を使用します。
関数計算をアクティブにします。
関数計算コンソール にログインします。UI のプロンプトに従って、一定量の無料リソースプランを申請することもできます。詳細については、「無料トライアルクォータ」をご参照ください。
関数計算イベント関数を作成します。
左側のナビゲーションウィンドウで、[関数] をクリックします。上部のナビゲーションバーで、Hologres インスタンスが存在するリージョンを選択します。
[関数] ページで、[関数の作成] をクリックして [関数の作成] ページに移動します。
[イベント関数] を選択し、次のパラメーターを構成します。その他のパラメーターは変更しないでください。詳細については、「イベント関数の作成」をご参照ください。
パラメーター
説明
関数名
カスタム関数名。たとえば、
unnestと入力します。ランタイム
[組み込みランタイム]/[Python]/[Python 3.10] を選択します。
コードアップロード方法
[ZIP をアップロード] を選択します。
コードパッケージ
記述およびパッケージ化されたコードパッケージをアップロードします。
次のコードを unnest.py に保存し、unnest.zip に圧縮します。
import json def unnest(event, context): evt = json.loads(event) data = evt.get('data', None) if data is None: raise ValueError('イベントに "data" キーがありません。') # 日本語訳 if not isinstance(data, list): raise ValueError('data はリストではありません。') # 日本語訳 res = list() for i in range(len(data)): if len(data[i]) != 1 or not isinstance(data[i], list): raise ValueError('data 内のアイテムはリストではありません。') # 日本語訳 for item in data[i][0]: res.append([i, item]) return json.dumps({'results': res})ハンドラー
unnest.unnestと入力します。
Hologres リモート関数を作成します。
説明HoloWeb プラットフォームで次の手順を完了する必要があります。詳細については、「HoloWeb に接続してクエリを実行する」をご参照ください。
CREATE EXTENSION IF NOT EXISTS function_compute; CREATE OR REPLACE FUNCTION rf_unnest(INTEGER []) RETURNS SETOF INTEGER STRICT LANGUAGE function_compute AS 'xxxxxxxxxxxxxxxxx.cn-shanghai-internal.fc.aliyuncs.com/unnest';テストデータを準備します。
CREATE TABLE test_array ( numbers INTEGER[] ); INSERT INTO test_array (numbers) VALUES (ARRAY[1, 3]), (ARRAY[2, 4]), ('{}'), (ARRAY[]::INTEGER[]), (NULL);リモート関数を呼び出します。
SELECT numbers, rf_unnest(numbers) FROM test_array; numbers | rf_unnest ---------+----------- {2,4} | 2 {2,4} | 4 {1,3} | 1 {1,3} | 3 (4 rows)