检查Spark

时间:2017-09-21 16:29:07

标签: scala apache-spark

我想检查spark中的数据类型并在其后创建两个RDD。一个带有验证记录的RDD和另一个带有错误的RDD。

我正在考虑创建以下方法:

def isInt (value: Any): Option[Int] = {
    case value: Int => Some(value)
    case _ => None
}

之后我可以根据列调用此方法,如果我得到None,则给出错误,如:

rdd.map{
     case(age) => if isInt(age).isEmpty (age,ErrorCodes.NOT_INT) else ((Int)age, None)
}

但我发现这种方法存在两个问题:

  1. 我有150列,因此为每个字段调用此方法并不是那么优雅。
  2. 如果一个字段发生变化,我必须更改我的代码,因此不太灵活。
  3. 还有其他办法吗?

1 个答案:

答案 0 :(得分:0)

在不知道上下文的情况下,这种事情的最原则性方法(我想要好的值和错误)可能是创建一个RDD的Either。例如:

import scala.util.{ Either, Left, Right }

case class NotAnInt(obj: Any)

def maybeIntRDD(anyRDD: RDD[Any]): RDD[Either[NotAnInt, Int]] =
   anyRDD.map {
     case i: Int => Right(i)
     case x => Left(NotAnInt(x))
   }

val eitherRDD: RDD[Either[NotAnInt, Int]] = maybeIntRDD(rdd)

// Get the ints and not ints
val intRDD: RDD[Int] = eitherRDD.flatMap(_.right.toOption)
val notIntRDD: Rdd[NotAnInt] = eitherRDD.flatMap(_.left.toOption)

// Double the ints, keep the NotAnInts
val doubled: RDD[Either[NotAnInt, Int]] = eitherRDD.map(_.right.map(_ * 2))

如果您有很多列,那么将ValidationFailure特征与一些案例类或案例对象一起扩展该特征可能对于不同类型的失败可能是有用的

def validateRow(row: YourColumnsTypeHere): Either[Seq[ValidationFailure], YourColumnTypeHere] = {
  // validation logic here, with errors accumulating in the failures Seq
  if (isValid)
    Right(row)
  else
    Left(failures)
}

val classifiedRDD = rdd.map(row => validateRow(row))