我在数据框上有一个 UDF,有时有一个可选/空字段。
我知道选项、大小写、匹配、重载等,但无法让它工作。
理想情况下我会喜欢这个,但是我得到一个空指针异常。
def getAfterImage = (data: String, key: String, jsonOLD_TABLE_FIELDS: String) => {
val jsonOLD_FIELDS = parse(jsonOLD_TABLE_FIELDS)
val jsonData = parse(data)
val jsonKey = if (key.isEmpty) parse(data) else parse(key)
val Diff(changed, added, deleted) = jsonKey diff jsonData
val afterImage = changed merge deleted merge jsonOLD_FIELDS
compact(render(afterImage)) // String
}
val afterImage = spark.udf.register("callUDFAI", getAfterImage)
val df5 = df4.withColumn("afterImage", afterImage(col("data"), col("key"), lit(""" { "OLD_FIELD_1":"", "OLD_FIELD_2":""} """)))
.select("meta", "afterImage")
Option
据我所知不能用于输入。
请注意,您引用的文档有点误导:虽然 Option can 用于返回“可空”基元,Option 不能用作 UDF 的输入(至少在 Spark 1.6 中,不确定 2.0)- Raphael Roth 2017 年 3 月 15 日 6:16 来自How to deal with Spark UDF input/output of primitive nullable type
所以,我试过这个:
val df5 = df4.withColumn("afterImage",
afterImage(col("data"),
when(col("key").isNull(),col("data").otherwise(col("key"))),
lit(""" { "OLD_FIELD_1":"", "OLD_FIELD_2":""} """)))
.select("meta", "afterImage")
返回:
command-3626869806869011:74: warning: Adaptation of argument list by inserting () is deprecated: leaky (Object-receiving) target makes this especially dangerous.
signature: Column.apply(extraction: Any): org.apache.spark.sql.Column
given arguments: <none>
after adaptation: Column((): Unit)
when(col("key").isNull(),col("data").otherwise(col("key"))),
^
我想做的事情并不困难。
我最终采用了这种方法,这是一个预处理步骤,但效果不佳。
val df5 = df4.withColumn("key2", when(col("key").isNull(), col("data").otherwise(col("key"))))
与第一个消息相同。
我想知道这种情况的方法是什么。
添加这个:
val df5 = df4.withColumn("key2", coalesce(col("key"), col("data")))
让它工作。但是有没有更优雅的解决方案呢? 逻辑是做作的,这不是重点。