ユーザー定義のスカラー関数 - Scala
この記事には、Scala ユーザー定義関数 (UDF) の例が含まれています。 UDF を登録する方法、UDF を呼び出す方法、および Spark SQL での部分式の評価順序に関する注意事項を示します。 詳しくは、 外部ユーザー定義スカラー関数 (UDF) を参照してください。
注:
Unity Catalog 対応コンピュート リソース上の Scala UDFs と共有アクセス モードを使用するには、Databricks Runtime 14.2 以降が必要です。
Spark SQLで UDF を呼び出す
spark.range(1, 20).createOrReplaceTempView("test")
%sql select id, square(id) as id_squared from test
DataFrames で UDF を使用する
import org.apache.spark.sql.functions.{col, udf}
val squared = udf((s: Long) => s * s)
display(spark.range(1, 20).select(squared(col("id")) as "id_squared"))
評価順序と null チェック
Spark SQL (SQL および DataFrame およびデータセット APIsを含む) は、部分式の評価順序を保証するものではありません。 特に、演算子または関数の入力は、必ずしも左から右、またはその他の固定された順序で評価されるとは限りません。 たとえば、論理 AND
式と OR
式には、左から右への "短絡" セマンティクスはありません。
したがって、 Boolean 式の副作用や評価順序、 WHERE
句や HAVING
句の順序は、クエリーの最適化や計画時に並べ替えることができるため、危険です。 具体的には、UDF が null チェックのために SQL の短絡セマンティクスに依存している場合、UDF を呼び出す前に null チェックが行われる保証はありません。 例えば
spark.udf.register("strlen", (s: String) => s.length)
spark.sql("select s from test1 where s is not null and strlen(s) > 1") // no guarantee
この WHERE
句は、null を除外した後に呼び出される strlen
UDF を保証するものではありません。
適切な null チェックを実行するには、次のいずれかを実行することをお勧めします。
UDF 自体をヌル対応にし、UDF 自体の内部でヌル チェックを行う
IF
式またはCASE WHEN
式を使用して null チェックを実行し、条件分岐で UDF を呼び出す
spark.udf.register("strlen_nullsafe", (s: String) => if (s != null) s.length else -1)
spark.sql("select s from test1 where s is not null and strlen_nullsafe(s) > 1") // ok
spark.sql("select s from test1 where if(s is not null, strlen(s), null) > 1") // ok
型付きリソースAPIs
注:
この機能は、Databricks Runtime 15.4 以降の共有アクセス モードを備えた Unity Catalog 対応クラスターでサポートされます。
型付きデータセットAPIs使用すると、ユーザー定義関数を使用して、結果のデータセットに対してマップ、フィルター、集計などの変換を実行できます。
たとえば、次の Scala アプリケーションでは、 map()
API を使用して、結果列の数値をプレフィックス付きの文字列に変更します。
spark.range(3).map(f => s"row-$f").show()
この例では map()
APIを使用していますが、これは filter()
、mapPartitions()
、foreach()
、foreachPartition()
、reduce()
、flatMap()
などの他の型指定されたデータセットAPIsにも適用されます。