尝试将 Map 作为参数传递给 Udf 时没有 typeTag 异常

Posted

技术标签:

【中文标题】尝试将 Map 作为参数传递给 Udf 时没有 typeTag 异常【英文标题】:No typeTag exception when trying to pass Map as parameter to Udf 【发布时间】:2016-07-14 08:38:53 【问题描述】:

我一直在尝试编写 UDF。当我尝试使用 SBT 构建包时收到错误消息。

 val getUiPropx = udf((prop_map:Map[String, String],prop:String,sub_prop:String,alt_prop:String) => 
if (prop_map.contains(prop)) 
  val ui_element_map = jsonStrToMap(prop_map(prop))
  if (ui_element_map.contains(sub_prop)) ui_element_map(sub_prop).toString() else "-1"

else 
  if (prop_map.contains(alt_prop)) prop_map(alt_prop).toString() else "-1"
 )

我收到的错误是 -

scala:87: No TypeTag available for Map[String,String]  [error] val getUiPropx = udf((prop_map:Map[String, String],prop:String,sub_prop:String,alt_prop:String) => 

问题是我什至还没有调用 udf,但我仍然收到错误。 有人可以解释一下错误吗?

编辑 -

正如下面的答案和线程中所建议的那样 - Pass array as an UDF parameter in Spark SQL 我将 udf 调用修改为 -

  def getUiPropx(prop_map:Map[String, String],prop:String,sub_prop:String,alt_prop:String) = 
udf(() => 
  if (prop_map.contains(prop)) 
    val ui_element_map = jsonStrToMap(prop_map(prop))
    if (ui_element_map.contains(sub_prop)) ui_element_map(sub_prop).toString() else "-1"
  
  else 
    if (prop_map.contains(alt_prop)) prop_map(alt_prop).toString() else "-1"
  
)

然后我调用它 -

val trnUiEventDf = hiveDf..withColumn("ui_element_id",getUiPropx(myMap,"ui_element","id","ui_element_id")(col("ep_map")))

我仍然在运行时收到一条错误消息,提示 Unit is not allowed in dataframes。 是不是因为我没有指定函数的任何返回类型?

【问题讨论】:

udf( (el1, el2, el3)..) 定义中的第一个元素是返回类型定义。但对你来说 prop_map 似乎是传递给函数的参数之一。 那是我为 udf 明确定义类型的时候。不是当我对 udf 进行隐式定义时。 【参考方案1】:

udf() 函数中的第一个参数应该具有某种与 sql 类型兼容的类型。它实际上表示您发送到该字段的字段的类型。对于 Map[String,String],sql 端没有关联类型。

【讨论】:

我通过将第一个字段设为 Unit 类型来处理此问题。然后将其转换为字符串,最后转换为 Map 类型。

以上是关于尝试将 Map 作为参数传递给 Udf 时没有 typeTag 异常的主要内容,如果未能解决你的问题,请参考以下文章

Pyspark 将函数作为参数传递给 UDF

将列表作为参数传递给 udf 方法

将查询作为参数传递给 udf 函数

将 UDF 方法作为参数传递给 KSQL 中的其他 UDF

如何将 UDF 的输入参数传递给 sapply

Pig 将关系作为参数传递给 UDF