Funções escalares definidas pelo usuário - Scala
Este artigo contém exemplos de funções definidas pelo usuário (UDF) do Scala. Ele mostra como registrar UDFs, como invocar UDFs e advertências sobre a ordem de avaliação de subexpressões no Spark SQL. Consulte Funções escalares definidas pelo usuário (UDFs) externas para obter mais detalhes.
Observação
Scala UDFs no Unity Catalog habilitado compute recurso com modo de acesso compartilhado requer Databricks Runtime 14.2 e acima.
registrar uma função como um UDF
val squared = (s: Long) => {
s * s
}
spark.udf.register("square", squared)
Chame o UDF no Spark SQL
spark.range(1, 20).createOrReplaceTempView("test")
%sql select id, square(id) as id_squared from test
Usar UDF com DataFrames
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"))
Ordem de avaliação e verificação nula
O Spark SQL (incluindo SQL e DataFrame e APIs dataset ) não garante a ordem de avaliação das subexpressões. Em particular, as entradas de um operador ou função não são necessariamente avaliadas da esquerda para a direita ou em qualquer outra ordem fixa. Por exemplo, as expressões lógicas AND
e OR
não têm semântica de "curto-circuito" da esquerda para a direita.
Portanto, é perigoso confiar nos efeitos colaterais ou na ordem de avaliação das expressões Boolean e na ordem das cláusulas WHERE
e HAVING
, pois essas expressões e cláusulas podem ser reordenadas durante a otimização e o planejamento query . Especificamente, se um UDF depende da semântica de curto-circuito no SQL para verificação nula, não há garantia de que a verificação nula ocorrerá antes de invocar o UDF. Por exemplo,
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
Esta cláusula WHERE
não garante que o strlen
UDF seja invocado após a filtragem de nulos.
Para executar a verificação nula adequada, recomendamos que você faça um dos seguintes:
Torne o próprio UDF com reconhecimento nulo e faça a verificação nula dentro do próprio UDF
Use as expressões
IF
ouCASE WHEN
para fazer a verificação nula e invocar a UDF em uma ramificação condicional
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 de conjuntos de dados tipados
Observação
Esse recurso é suportado no Unity Catalog habilitado clusters com modo de acesso compartilhado em Databricks Runtime 15.4 e acima.
Conjunto de dados digitado APIs permite a execução de transformações como mapa, filtro e agregações no conjunto de dados resultante com uma função definida pelo usuário.
Por exemplo, o aplicativo Scala a seguir usa o map()
API para modificar um número em uma coluna de resultados para uma cadeia de caracteres prefixada.
spark.range(3).map(f => s"row-$f").show()
Embora este exemplo use o map()
API, isso também se aplica a outros conjuntos de dados digitados APIs, como filter()
, mapPartitions()
, foreach()
, foreachPartition()
, reduce()
e flatMap()
.