Je suis en train de tester l'étincelle à l'aide de scala. Nous lisons généralement des fichiers json qui doivent être manipulés comme dans l'exemple suivant:
test.json:
{"a":1,"b":[2,3]}
val test = sqlContext.read.json("test.json")
Comment puis-je le convertir au format suivant:
{"a":1,"b":2}
{"a":1,"b":3}
Vous pouvez utiliser la fonction explode
:
scala> import org.Apache.spark.sql.functions.explode
import org.Apache.spark.sql.functions.explode
scala> val test = sqlContext.read.json(sc.parallelize(Seq("""{"a":1,"b":[2,3]}""")))
test: org.Apache.spark.sql.DataFrame = [a: bigint, b: array<bigint>]
scala> test.printSchema
root
|-- a: long (nullable = true)
|-- b: array (nullable = true)
| |-- element: long (containsNull = true)
scala> val flattened = test.withColumn("b", explode($"b"))
flattened: org.Apache.spark.sql.DataFrame = [a: bigint, b: bigint]
scala> flattened.printSchema
root
|-- a: long (nullable = true)
|-- b: long (nullable = true)
scala> flattened.show
+---+---+
| a| b|
+---+---+
| 1| 2|
| 1| 3|
+---+---+
il est souvent suggéré d’exploser, mais cela provient de l’API DataFrame non typée et, étant donné que vous utilisez Dataset, je pense que l’opérateur flatMap pourrait être plus approprié (voir org.Apache.spark.sql.Dataset ).
flatMap[U](func: (T) ⇒ TraversableOnce[U])(implicit arg0: Encoder[U]): Dataset[U]
(Spécifique à Scala) Retourne un nouveau jeu de données en appliquant d'abord une fonction à tous les éléments de ce jeu de données, puis en aplatissant les résultats.
Vous pouvez l'utiliser comme suit:
val ds = Seq(
(0, "Lorem ipsum dolor", 1.0, Array("prp1", "prp2", "prp3")))
.toDF("id", "text", "value", "properties")
.as[(Integer, String, Double, scala.List[String])]
scala> ds.flatMap { t =>
t._4.map { prp =>
(t._1, t._2, t._3, prp) }}.show
+---+-----------------+---+----+
| _1| _2| _3| _4|
+---+-----------------+---+----+
| 0|Lorem ipsum dolor|1.0|prp1|
| 0|Lorem ipsum dolor|1.0|prp2|
| 0|Lorem ipsum dolor|1.0|prp3|
+---+-----------------+---+----+
// or just using for-comprehension
for {
t <- ds
prp <- t._4
} yield (t._1, t._2, t._3, prp)