似乎无法在UDF中使用可选/默认参数。 jira建议针对这种用例使用两个不同的UDF。
我的代码如下:
dataset.select(RecordProvider.getKeyUDF(sparkArguments.getDatasetArguments)(col(hashKeyName), col(rangeKeyName)).as("key"),
RecordProvider.getValueUDF(avroSchema)(to_json(struct(dataset.columns.map(col): _*))).as("value"))
UDF看起来像这样,
def getKeyUDF(datasetArguments: DatasetArguments) = udf((hashKey: String, rangeKey: String) => {
.....
})
在这种情况下,rangeKeyName
可以为null,这意味着该数据集不存在rangeKey
列。我的UDF已注册为rangeKey
处理null的函数。
我正在努力在没有{if1)if的情况下完成此工作,而在整个dataset.select
周围则有两个UDF。那是唯一的方法吗?另外,由于我使用的是curring,因此无法为UDF使用函数(val
),因此必须坚持使用方法(def
)。
答案 0 :(得分:1)
您可以添加不存在的仅具有空值的列。或者,您可以使用if-else检查该列是否存在,并将rangeKey
替换为不存在的空列。这样,您就可以在两种情况下使用相同的UDF
。
添加不存在的空列:
if (!dataset.columns.contains(rangeKeyName))
dataset = dataset.withColumn("rangeKeyName", lit(None).cast(StringType()))
使用if-else:
if (dataset.columns.contains(rangeKeyName)) {
// Same as before
} else {
dataset.select(RecordProvider.getKeyUDF(sparkArguments.getDatasetArguments)(col(hashKeyName), lit(None).cast(StringType())).as("key"),
RecordProvider.getValueUDF(avroSchema)(to_json(struct(dataset.columns.map(col): _*))).as("value"))
}
答案 1 :(得分:1)
您也可以在列本身上使用when(condition,result1).otherwise(result2)。 lit()可用于避免NULL。可以是任何数据类型。
import org.apache.spark.sql.functions._
dataset.select(getKeyUDF(when(col("hashKeyName").isNull,lit("")).otherwise(col("hashKeyName")),col("rangeKeyName")).as("key"))