[英]How to convert json into RDD[json]
我想在Spark中编写json对象,但是当我尝试使用sc.parallelize将其转换为RDD时,它再次将其转换回字符串
import scala.util.parsing.json._
import org.apache.spark.sql._
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions.lit
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._
val df = Seq((2012, 8, "Batman", 9.8),
(2012, 9, "Batman", 10.0),
(2012, 8, "Hero", 8.7),
(2012, 10, "Hero", 5.7),
(2012, 2, "Robot", 5.5),
(2011, 7, "Git", 2.0),
(2010, 1, "Dom", 2.0),
(2019, 3, "Sri", 2.0)).toDF("year", "month", "title", "rating")
case class Rating(year:Int, month:Int, title:String, rating:Double)
import scala.collection.JavaConversions._
val ratingList = df.as[Rating].collectAsList
import java.io._
val output = for (c <- ratingList) yield
{
val json = ("record" ->
("year" -> c.year) ~
("month" -> c.month) ~
("title" -> c.title) ~
("rating" -> c.rating))
compact(render(json))
}
output.foreach(println)
在这个阶段,它是一个json对象,一切都很好。 但是当我将其转换为RDD时,spark将其视为字符串
val outputDF = sc.parallelize(output).toDF("json")
outputDF.show()
outputDF.write.mode("overwrite").json("s3://location/")
输出为:
{"test":{"json":"{\"record\":{\"year\":2012,\"month\":8,\"title\":\"Batman\",\"rating\":9.8}}"}}
当您调用compact
-您从呈现的json中创建String。 看到:
scala> val json = ("name" -> "joe") ~ ("age" -> 35)
scala> compact(render(json))
res2: String = {"name":"joe","age":35}
这意味着您的output
是字符串的集合。 当您并行化它时,将得到RDD [String]。
您可能想返回render
函数的结果以获取JSON对象的集合。 但是您需要为此检查文档。
当然,Spark不知道如何使用toDF()
函数将JSON对象从第三方库转换为DataFrame。 可能您可以执行以下操作:
val anotherPeopleRDD = sc.parallelize(
"""{"name":"Yin","address":{"city":"Columbus","state":"Ohio"}}""" :: Nil)
val anotherPeople = sqlContext.read.json(anotherPeopleRDD)
因此,基本上具有RDD [String],然后将其读取为JSON。
和顺便说一句
为什么首先要这样做:
val ratingList = df.as[Rating].collectAsList
val output = for (c <- ratingList) yield
{
val json = ("record" ->
("year" -> c.year) ~
("month" -> c.month) ~
("title" -> c.title) ~
("rating" -> c.rating))
compact(render(json))
}
接着:
val outputDF = sc.parallelize(output).toDF("json")
为什么不像这样只处理集群中的所有数据:
df.as[Rating].map{c =>
val json = ("record" ->
("year" -> c.year) ~
("month" -> c.month) ~
("title" -> c.title) ~
("rating" -> c.rating))
compact(render(json))
}
这样,它将更加高效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.