首页 > 解决方案 > 将 StructType 定义为函数 Spark-Scala 2.11 的输入数据类型

问题描述

我正在尝试在 scala 中编写 Spark UDF,我需要定义一个函数的输入数据类型

我有一个带有 StructType 的模式变量,如下所述。

import org.apache.spark.sql.types._

val relationsSchema = StructType(
      Seq(
        StructField("relation", ArrayType(
          StructType(Seq(
            StructField("attribute", StringType, true),
            StructField("email", StringType, true),
            StructField("fname", StringType, true),
            StructField("lname", StringType, true)
            )
          ), true
        ), true)
      )
    )

我正在尝试编写如下所示的函数

val relationsFunc: Array[Map[String,String]] => Array[String] = _.map(do something)
val relationUDF = udf(relationsFunc)

input.withColumn("relation",relationUDF(col("relation")))

上面的代码抛出异常

org.apache.spark.sql.AnalysisException: cannot resolve 'UDF(relation)' due to data type mismatch: argument 1 requires array<map<string,string>> type, however, '`relation`' is of array<struct<attribute:string,email:string,fname:string,lname:string>> type.;;
'Project [relation#89, UDF(relation#89) AS proc#273]

如果我将输入类型指定为

val relationsFunc: StructType => Array[String] =

我无法实现逻辑,因为 _.map 给了我元数据、文件名等。

请建议如何在以下函数中将关系模式定义为输入数据类型。

val relationsFunc: ? => Array[String] = _.map(somelogic)

标签: scalaapache-sparkapache-spark-sql

解决方案


您的关系下的结构是 a Row,因此您的函数应具有以下签名:

val relationsFunc: Array[Row] => Array[String]

那么您可以按位置或名称访问您的数据,即:

{r:Row => r.getAs[String]("email")}

推荐阅读