sparkcontext spark que introduccion examples ejemplo batch arquitectura scala apache-spark tuples rdd

scala - que - spark ejemplo



¿Cómo pongo una clase de caso en un rdd y hago que actúe como una tupla(par)? (1)

Extender TupleN no es una buena idea por varias razones, una de las mejores es el hecho de que está obsoleto, y en 2.11 ni siquiera es posible extender TupleN con una clase de caso. Incluso si convierte su Foo una clase no -deprecation , definirla en 2.11 con -deprecation le mostrará esto: "warning: la herencia de la clase Tuple2 en el paquete scala está en desuso: Tuples se hará definitiva en una versión futura".

Si lo que te importa es la comodidad de uso y no te importa la sobrecarga (casi sin duda) de la conversión a una tupla, puedes enriquecer un RDD[Foo] con la sintaxis proporcionada por PairRDDFunctions con una conversión como esta:

import org.apache.spark.rdd.{ PairRDDFunctions, RDD } case class Foo(k: String, v1: String, v2: String) implicit def fooToPairRDDFunctions[K, V] (rdd: RDD[Foo]): PairRDDFunctions[String, (String, String)] = new PairRDDFunctions( rdd.map { case Foo(k, v1, v2) => k -> (v1, v2) } )

Y entonces:

scala> val rdd = sc.parallelize(List(Foo("a", "b", "c"), Foo("d", "e", "f"))) rdd: org.apache.spark.rdd.RDD[Foo] = ParallelCollectionRDD[6] at parallelize at <console>:34 scala> rdd.mapValues(_._1).first res0: (String, String) = (a,b)

La razón por la cual su versión con Foo extiende Tuple2[String, (String, String)] no funciona es que RDD.rddToPairRDDFunctions dirige a un RDD[Tuple2[K, V]] y el RDD no es covariante en su parámetro de tipo, por lo que RDD[Foo] no es un RDD[Tuple2[K, V]] . Un ejemplo más simple podría aclarar esto:

case class Box[A](a: A) class Foo(k: String, v: String) extends Tuple2[String, String](k, v) class PairBoxFunctions(box: Box[(String, String)]) { def pairValue: String = box.a._2 } implicit def toPairBoxFunctions(box: Box[(String, String)]): PairBoxFunctions = new PairBoxFunctions(box)

Y entonces:

scala> Box(("a", "b")).pairValue res0: String = b scala> Box(new Foo("a", "b")).pairValue <console>:16: error: value pairValue is not a member of Box[Foo] Box(new Foo("a", "b")).pairValue ^

Pero si haces Box covariante ...

case class Box[+A](a: A) class Foo(k: String, v: String) extends Tuple2[String, String](k, v) class PairBoxFunctions(box: Box[(String, String)]) { def pairValue: String = box.a._2 } implicit def toPairBoxFunctions(box: Box[(String, String)]): PairBoxFunctions = new PairBoxFunctions(box)

…todo está bien:

scala> Box(("a", "b")).pairValue res0: String = b scala> Box(new Foo("a", "b")).pairValue res1: String = b

Sin embargo, no puede hacer que RDD covariante, por lo que definir su propia conversión implícita para agregar la sintaxis es su mejor opción. Personalmente, probablemente elegiría hacer la conversión explícitamente, pero este es un uso relativamente poco horrible de las conversiones implícitas.

Digamos, por ejemplo, tengo una clase de caso simple

case class Foo(k:String, v1:String, v2:String)

¿Puedo obtener chispa para reconocer esto como una tupla con el propósito de algo como esto, sin convertir a una tupla en, digamos un mapa o una tecla Por paso.

val rdd = sc.parallelize(List(Foo("k", "v1", "v2"))) // Swap values rdd.mapValues(v => (v._2, v._1))

Ni siquiera me importa si pierde la clase de caja original después de tal operación. Intenté lo siguiente sin suerte. Soy bastante nuevo para Scala, ¿me estoy perdiendo algo?

case class Foo(k:String, v1:String, v2:String) extends Tuple2[String, (String, String)](k, (v1, v2))

editar: en el fragmento anterior, la clase caso extiende Tuple2, esto no produce el efecto deseado de que la clase RDD y las funciones no lo tratan como una tupla y permiten PairRDDFunctions, como mapValues, values, reduceByKey, etc.