【问题标题】:How to sort schema columns of nested arrays and structs alphabetically in scala spark?如何在scala spark中按字母顺序对嵌套数组和结构的模式列进行排序?
【发布时间】:2021-07-12 03:31:56
【问题描述】:

我有以下架构的数据框。我希望包括嵌套字段在内的所有列都应按字母顺序排序。我想要它在 scala spark 中。

root
 |-- metadata2: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- attribute2: string (nullable = true)
 |    |    |-- attribute1: string (nullable = true)
 |-- metadata3: string (nullable = true)
 |-- metadata1: struct (containsNull = true)
 |    |-- attribute2: string (nullable = true)
 |    |-- attribute1: string (nullable = true)

当我使用 schema.sortBy(_.name) 进行排序时,我得到了 schema(嵌套数组和结构类型字段未排序)

root
 |-- metadata1: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- attribute2: string (nullable = true)
 |    |    |-- attribute1: string (nullable = true)
 |-- metadata2: struct (containsNull = true)
 |    |-- attribute2: string (nullable = true)
 |    |-- attribute1: string (nullable = true)
 |-- metadata3: string (nullable = true)

我想要的架构如下。 (即使是 metadata1(ArrayType) 和 metadata2(StructType) 里面的列也要排序)

root
 |-- metadata1: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- attribute1: string (nullable = true)
 |    |    |-- attribute2: string (nullable = true)
 |-- metadata2: struct (containsNull = true)
 |    |-- attribute1: string (nullable = true)
 |    |-- attribute2: string (nullable = true)
 |-- metadata3: string (nullable = true)

提前致谢。

【问题讨论】:

    标签: scala apache-spark struct apache-spark-sql


    【解决方案1】:

    StructType 的版本:

    import spark.implicits._
    import org.apache.spark.sql.types.{ArrayType, StringType, StructField, StructType}
    
    val schema = StructType(Seq(
      StructField("metadata2",       StructType(
        Seq(StructField("attribute2", StringType),
          StructField("attribute1", StringType)))),
      StructField("metadata3", StringType),
      StructField("metadata1", ArrayType(StringType)
      )
    ))
    
    schema.foreach(println _)
    //  StructField(metadata2,StructType(StructField(attribute2,StringType,true), StructField(attribute1,StringType,true)),true)
    //  StructField(metadata3,StringType,true)
    //  StructField(metadata1,ArrayType(StringType,true),true)
    
    
    val schemaResult = schema.sortBy(_.name).map{c =>
      c.dataType match {
        case structType: StructType => StructField(c.name, StructType(structType.fields.sortBy(_.name)))
        case _ => c
      }
    }
    
    schemaResult.foreach(println _)
    //  StructField(metadata1,ArrayType(StringType,true),true)
    //  StructField(metadata2,StructType(StructField(attribute1,StringType,true), StructField(attribute2,StringType,true)),true)
    //  StructField(metadata3,StringType,true)
    println(schemaResult)
    //  List(StructField(metadata1,ArrayType(StringType,true),true), StructField(metadata2,StructType(StructField(attribute1,StringType,true), StructField(attribute2,StringType,true)),true), StructField(metadata3,StringType,true))
    

    【讨论】:

    • 感谢您的解决方案,metadata2 是一个结构类型的数组。在我的用例中,我有多个嵌套字段,例如 Struct of Struct 和 Array of Struct of Struct 字段。解决方案应该排序直到深度嵌套的字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    相关资源
    最近更新 更多