StructType的注意事项
实现代码
val schema = StructType(
List(
StructField("1",IntegerType,true)
//....N个字段。。。
)
)
解析
StructType( ) 中可以放List、Seq
StructField( )
源码:
case class StructField(
name: String,
dataType: DataType,
nullable: Boolean = true,
metadata: Metadata = Metadata.empty) {}
一个StructType对象,可以有多个StructField,同时它也可以用名字(name)来提取,与Map可以用key来提取value一样,但是他StructType提取的是整条字段的信息。
方法1 :
// 使用Spark-Core操作
val countsdf = logsDF.rdd.map(row =>{
val province = row.getAs[String]("provincename")
val city = row.getAs[String]("cityname")
((province,city),1)
}).reduceByKey(_+_).map(x=>(x._1._1,x._1._2,x._2.toDouble)).map(Row.fromTuple(_))
val schema = StructType(
List(
StructField("province",StringType,true),
StructField("city",StringType,true),
StructField("cts",DoubleType,true)
)
)
spark.createDataFrame(countsdf,schema)
.repartition(1)
.write.mode(SaveMode.Append).json(output)
Tips:
-
如果不使用Row.fromXXX直接在第一个map中Row(x,y,z)
会导致报错:列名对应不上,不能直接这样子row多个数据
-
直接不使用row
会导致无法重载createDataFrame方法
方法2 :
// 使用Spark-Core操作
val countsdf = logsDF.rdd.map(row =>{
val province = row.getAs[String]("provincename")
val city = row.getAs[String]("cityname")
((province,city),1)
}).reduceByKey(_+_).map(x=>(x._1._1,x._1._2,x._2)
val schema = Seq("province","city","cts")
spark.createDataFrame(countsdf)
.toDF(schema1:_*)
.repartition(1)
.write.mode(SaveMode.Append).json(output)
Tips:
使用此方法需要保证rdd中的列数一定要和schema对应