Exploser tableau dans apache spark bloc de Données

Je suis en train de les aplatir un schéma de l'existant dataframe avec des champs imbriqués. La Structure de ma dataframe est quelque chose comme ça:

root  
|-- Id: long (nullable = true)  
|-- Type: string (nullable = true)  
|-- Uri: string (nullable = true)    
|-- Type: array (nullable = true)  
|    |-- element: string (containsNull = true)  
|-- Gender: array (nullable = true)  
|    |-- element: string (containsNull = true)

Type et le sexe peut contenir de nombreux éléments, un élément ou une valeur null.
J'ai essayé d'utiliser le code suivant:

var resDf = df.withColumn("FlatType", explode(df("Type")))

Mais comme un résultat, en partant, d'un bloc de données, je lâche les lignes pour lesquelles j'ai eu des valeurs null dans la colonne Type. Cela signifie, par exemple, si j'ai 10 lignes et 7 lignes de type est nul et 3 type n'est pas null, après j'utilise exploser en résultant bloc de données, je n'ai que trois lignes.

Comment puis-je garder les lignes avec des valeurs nulles mais exploser tableau de valeurs?

J'ai trouvé une sorte de solution de contournement, mais encore coincé dans un seul endroit. Pour les types standard, nous pouvons effectuer les opérations suivantes:

def customExplode(df: DataFrame, field: String, colType: String): org.apache.spark.sql.Column = {
var exploded = None: Option[org.apache.spark.sql.Column]
colType.toLowerCase() match {
  case "string" => 
    val avoidNull = udf((column: Seq[String]) =>
    if (column == null) Seq[String](null)
    else column)
    exploded = Some(explode(avoidNull(df(field))))
  case "boolean" => 
    val avoidNull = udf((xs: Seq[Boolean]) =>
    if (xs == null) Seq[Boolean]()
    else xs)
    exploded = Some(explode(avoidNull(df(field))))
  case _ => exploded = Some(explode(df(field)))
}
exploded.get

}

Et après que juste l'utiliser comme ceci:

val explodedField = customExplode(resultDf, fieldName, fieldTypeMap(field))
resultDf = resultDf.withColumn(newName, explodedField)

Cependant, j'ai un problème de type struct pour ce type de structure:

 |-- Address: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- AddressType: array (nullable = true)
 |    |    |    |-- element: string (containsNull = true) 
 |    |    |-- DEA: array (nullable = true)
 |    |    |    |-- element: struct (containsNull = true)
 |    |    |    |    |-- Number: array (nullable = true)
 |    |    |    |    |    |-- element: string (containsNull = true)
 |    |    |    |    |-- ExpirationDate: array (nullable = true)
 |    |    |    |    |    |-- element: timestamp (containsNull = true)
 |    |    |    |    |-- Status: array (nullable = true)
 |    |    |    |    |    |-- element: string (containsNull = true)

Comment traiter ce genre de schéma lorsque le DEA est null?

Vous en remercie d'avance.

P. S. j'ai essayé d'utiliser des vues Latérales, mais le résultat est le même.

OriginalL'auteur Artem | 2016-09-11