web-dev-qa-db-fra.com

Erreur lors de l'explosion d'une colonne struct dans Spark

J'ai une trame de données dont le schéma ressemble à ceci:

event: struct (nullable = true)
|    | event_category: string (nullable = true)
|    | event_name: string (nullable = true)
|    | properties: struct (nullable = true)
|    |    | ErrorCode: string (nullable = true)
|    |    | ErrorDescription: string (nullable = true)

J'essaie d'exploser la colonne structproperties en utilisant le code suivant:

df_json.withColumn("event_properties", explode($"event.properties"))

Mais il lève l'exception suivante:

cannot resolve 'explode(`event`.`properties`)' due to data type mismatch: 
input to function explode should be array or map type, 
not StructType(StructField(IDFA,StringType,true),

Comment faire exploser la colonne properties?

7
shiva.n404

Vous pouvez utiliser explode dans un array ou mapcolonnes vous devez donc convertir le propertiesstruct à array puis appliquez la fonction explode comme ci-dessous

import org.Apache.spark.sql.functions._
df_json.withColumn("event_properties", explode(array($"event.properties.*"))).show(false)

Vous devriez avoir l'exigence souhaitée

6
Ramesh Maharjan

comme l'indique le message d'erreur, vous ne pouvez exploser que les types de tableau ou de carte, pas les colonnes de type struct.

Tu peux juste faire

df_json.withColumn("event_properties", $"event.properties")

Cela va générer une nouvelle colonne event_properties, qui est également de type struct

Si vous souhaitez convertir chaque élément de la structure dans une nouvelle colonne, vous ne pouvez pas utiliser withColumn, vous devez faire un select avec un caractère générique *:

df_json.select($"event.properties.*")
4
Raphael Roth

Vous pouvez utiliser ce qui suit pour aplatir la structure. Explode ne fonctionne pas pour la structure comme l'indique le message d'erreur.

val explodeDF = parquetDF.explode($"event") { 
case Row(properties: Seq[Row]) => properties.map{ property =>
  val errorCode = property(0).asInstanceOf[String]
  val errorDescription = property(1).asInstanceOf[String]
  Event(errorCode, errorDescription, email, salary)
 }
}.cache()
display(explodeDF)
0
Anush