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 struct
properties
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
?
Vous pouvez utiliser explode
dans un array
ou map
colonnes vous devez donc convertir le properties
struct
à 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
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.*")
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)