火花连接功能错误

时间:2017-07-06 14:42:07

标签: scala apache-spark dataframe apache-spark-sql

我有一个很大的数据框,我想用一个小的csv文件加入它。 所以我播放了我的小文件:

val rdd = sc.textFile("hdfs:///user/zed/file/app_desc")
val id_dec = sc.broadcast(rdd.map(line=>(line.split(";")(0),line.split(";")(1))).collectAsMap) 

我创建一个函数来获取id(输入)并返回描述

def extract_connection_type(input:Integer): String = {
  if (input == null || input.length() == 0)
    input;
  else try {
    id_dec.value.get(input)
  } catch {
     case e: Exception => throw new IOException("UDF:Caught exception processing input row :" + input + e.toString);
  }
}

之后,当我创建模式时,我使用此函数来进行连接

def structure(line: String): structure_Ot = {
  val fields = line.split("\\\t",-1);
  val Name1 = fields(0);
  val Name2 = fields(1);
  val Appd = fields(2).toInt;
  val App = extract_connection_type(Appd);
  val ot_str = new structure_Ot(Name1, Name2, App)
  ot_str
}

但是我收到了这个错误:

<console>:93: error: type mismatch;
 found   : String
 required: Int

甚至当我将输入更改为Integer时;我的错误更改为:

found   : String
required: Int 

出现此错误的原因是什么?

1 个答案:

答案 0 :(得分:2)

您的代码中存在很多类型不匹配的问题,您需要解决所有问题:

  1. id_dec的类型为Broadcast[Map[String, String]](因为您创建了RDD[(String, String)],然后在结果上调用collectAsMapbroadcast;在extract_connection_type,您拨打id_dec.value.get(input),其中input的类型为Int,地图的密钥为String。您可以通过将input的类型更改为String,或通过在第一个中收集和广播id_decBroadcast[Map[Int, String]]更改为RDD[(Int, String)]来解决此问题。地点;如果您选择前者,则还必须调整structure功能,因此它会传递String而不是Int

  2. 使用id_dec.value.get(input)的另一个问题是get会返回Option[V](其中V是地图值的类型)而不是V一个apply。您可以使用id_dec.value(input)方法(隐式):String,如果找不到匹配的密钥,将返回val rdd = sc.textFile("hdfs:///user/zed/file/app_desc") val id_dec: Broadcast[Map[String, String]] = sc.broadcast(rdd.map(line=>(line.split(";")(0),line.split(";")(1))).collectAsMap) def extract_connection_type(input: String): String = { if (input == null || input.length() == 0) input else try { id_dec.value(input) } catch { case e: Exception => throw new IOException("UDF:Caught exception processing input row :" + input + e.toString); } } def structure(line: String): structure_Ot = { val fields = line.split("\\\t",-1) val Name1 = fields(0) val Name2 = fields(1) val Appd = fields(2) val App = extract_connection_type(Appd) val ot_str = structure_Ot(Name1, Name2, App.toInt) ot_str } 或抛出异常

  3. 总而言之,这是您的代码的编译版本:

    id_dec

    自己解决这些问题的一个好方法是明确键入您定义的每个值;通过这种方式,您可以更清楚地看到错误的位置 - 如果您希望<pre></pre> 具有某种类型,则错误将指向其分配,如果存在分配了错误类型的问题