Spark获取嵌套json的列名

时间:2016-01-27 15:37:36

标签: java json nested apache-spark-sql spark-dataframe

我试图通过DataFrames从嵌套的JSON中获取列名。架构如下:

root
 |-- body: struct (nullable = true)
 |    |-- Sw1: string (nullable = true)
 |    |-- Sw2: string (nullable = true)
 |    |-- Sw3: string (nullable = true)
 |    |-- Sw420: string (nullable = true)
 |-- headers: struct (nullable = true)
 |    |-- endDate: string (nullable = true)
 |    |-- file: string (nullable = true)
 |    |-- startDate: string (nullable = true)

我可以获得列名" body"和#34;标题"使用df.columns()但是当我尝试从df.select(" body")。列中获取主体的列名(例如:Sw1,Sw2,...)时,它总是给我正文栏。

有什么建议吗? :)

4 个答案:

答案 0 :(得分:5)

如果问题是如何查找嵌套列名称,可以通过检查DataFrame的schema来执行此操作。模式表示为StructType,其中包含其他DataType个对象的字段(包括其他嵌套结构)。如果你想发现所有的字段,你必须递归地走这棵树。例如:

import org.apache.spark.sql.types._
def findFields(path: String, dt: DataType): Unit = dt match {
  case s: StructType => 
    s.fields.foreach(f => findFields(path + "." + f.name, f.dataType))
  case other => 
    println(s"$path: $other")
}

它遍历树并打印出所有叶子字段及其类型:

val df = sqlContext.read.json(sc.parallelize("""{"a": {"b": 1}}""" :: Nil))
findFields("", df.schema)

prints: .a.b: LongType

答案 1 :(得分:1)

如果嵌套的 json 有一个 StructType 数组,那么可以使用下面的代码(下面的代码是对 Michael Armbrust 给出的代码的扩展)

import org.apache.spark.sql.types._

def findFields(path: String, dt: DataType): Unit = dt match {
  case s: StructType => 
    s.fields.foreach(f => findFields(path + "." + f.name, f.dataType))
  case s: ArrayType => 
    findFields(path, s.elementType)
  case other => 
    println(s"$path")
}

答案 2 :(得分:0)

非常简单:df.select("body.Sw1", "body.Sw2")

答案 3 :(得分:0)

要获取嵌套列名,请使用如下代码:

从主要方法调用如下:

findFields(df,df.schema)

方法:

def findFields(df:DataFrame,dt: DataType) = 
{
    val fieldName = dt.asInstanceOf[StructType].fields
    for (value <- fieldName) 
    {
      val colNames = value.productElement(1).asInstanceOf[StructType].fields
      for (f <- colNames)
      {
         println("Inner Columns of "+value.name+" -->>"+f.name)
      }
   }

}

注意:仅当第一组列都是结构类型时才会起作用。