如何在用户定义的函数中使用自定义类型?

Posted

技术标签:

【中文标题】如何在用户定义的函数中使用自定义类型?【英文标题】:How to use custom type in user-defined function? 【发布时间】:2017-05-05 14:44:27 【问题描述】:

我需要编写一个具有特定类型作为输入的用户定义函数

spark.udf.register("udf", (p:Point) => distance(p.x, p.y))

我创建了一个案例类点

case class Point(val x: Double, val y: Double)

当我在 Sql 查询中使用 udf 时,它不起作用。有什么帮助吗?

【问题讨论】:

在SQL查询中,“Point”类型是否可用?调用 UDF 您需要传递数据类型为“点”的列 No Point 类型不存在,如何定义? 【参考方案1】:

定义您的案例类并将其用作数据集架构的“源”。

case class Point(val x: Double, val y: Double)
val points = Seq(Point(0,0), Point(0,1)).toDF
scala> points.show
+---+---+
|  x|  y|
+---+---+
|0.0|0.0|
|0.0|1.0|
+---+---+

您可能已经注意到,案例类只是数据集的模式(即结构)。换句话说,在处理此类数据集时,您不能编写一个接受Point 对象的用户定义函数。

一种可能的解决方案是不使用用户定义的函数,而是键入Dataset 并将函数注册为 UDF,而不是常规的 Scala 函数(或方法)。

scala> val points = Seq(Point(0,0), Point(0,1)).toDS
points: org.apache.spark.sql.Dataset[Point] = [x: double, y: double]

def distance(x: Double, y: Double) = y - x
val myFn = (p:Point) => distance(p.x, p.y)
scala> points.map(myFn).show
+-----+
|value|
+-----+
|  0.0|
|  1.0|
+-----+

【讨论】:

【参考方案2】:

我不知道你的确切要求,但看看你的代码,我提出了一些逻辑。

希望您的查询/表有两个单独的值,即 X 和 Y。 您可以按如下方式重新构建您的 udf

spark.udf.register("udf", (x:Double, y:Double) => distance(x,y))

现在您可以使用withCoumn() 使用新的udf 并传递两个单独的参数X 和Y

让我知道还有什么需要注意的。

【讨论】:

@syl 如果对您有用,请确保答案正确 这仍然无法解决嵌套自定义类型的情况

以上是关于如何在用户定义的函数中使用自定义类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JNI 中使用自定义类类型参数调用 Java 函数

java 如何让用户自定义函数呢?

SQLSERVER里如何自定义函数?

在函数文件中更改自定义帖子类型 slug

如何在高级自定义字段插件中使用用户字段类型显示用户名

09.AutoMapper 之自定义类型转换器(Custom Type Converters)