假设我有一些格式的json数据:
{
"opp_id": "IxexyLDIIk",
"id": "IxexyLDIIk",
"date": 1488465636,
"imp": {
"id": "1",
"banner": [{
"w": 728,
"h": 90,
"pos": 1
}]
}
}
我想创建一个架构,其中作为地图的字段imp
可以接受任意数量的值。我看到的问题是我不能这样做,因为在imp内部有一个字段banner
,它是一个数组。
如何在spark中创建这样的架构?这是指定一个可以包含任何键的映射,其中一些键具有特定的模式。
理想情况下,我想在json架构中使用解决方案,但scala / pyspark很好
澄清一下,我想知道是否可以这样做:
df = spark.read.json(data, schema=THIS_IS_WHAT_I_NEED)
答案 0 :(得分:0)
尝试使用以下内容:
sqlContext.read.
schema(
ScalaReflection.schemaFor[Some_Case_Class].dataType.asInstanceOf[StructType]
).json(some_json)
您的案例类看起来像这样的代码:
case class Banner(w : Int, h : Int, pos : Int)
case class Imp(id : Long, Banner : List[Banner])
case class DataSet(opp_id : Long, id :Long, date : Long, imp : Imp)
你的反思可能是这样的:
ScalaReflection.schemaFor[DataSet].dataType.asInstanceOf[StructType]
你需要:
import org.apache.spark.sql.catalyst.ScalaReflection
import org.apache.spark.sql.types.StructType
我明白了:
res7: org.apache.spark.sql.types.StructType = StructType(StructField(opp_id,LongType,false), StructField(id,LongType,false), StructField(date,LongType,false), StructField(imp,StructType(StructField(id,LongType,false), StructField(banner,ArrayType(StructType(StructField(w,IntegerType,false), StructField(h,IntegerType,false), StructField(pos,IntegerType,false)),true),true)),true))
如果你手动将它键入你的代码中,你可能看不到一些Scala Spark Shell的细微差别 - 即需要在某些地方插入Seq
以便真正看到模式有一些系列数据。为了更清楚这些是什么,你可以发出:
res7.printTreeString
root
|-- opp_id: long (nullable = false)
|-- id: long (nullable = false)
|-- date: long (nullable = false)
|-- imp: struct (nullable = true)
| |-- id: long (nullable = false)
| |-- banner: array (nullable = true)
| | |-- element: struct (containsNull = true)
| | | |-- w: integer (nullable = false)
| | | |-- h: integer (nullable = false)
| | | |-- pos: integer (nullable = false)
由于关于这个Seq
部分还有其他问题和答案,我现在推迟了你可能需要的工具。