[英]Parse JSON Object in spark scala
我有一組 json 對象,我想使用 spark scala 讀取該數據,我會將示例文件數據放在一個包含 100 多個對象的文件下方。
//文件1
{
"id":"31342547689",
"Name":"Jacob",
"Sex":"M",
"Destination":"Accounts"
}
{
"id":"987875637898",
"Name":"Martin",
"Sex":"M",
"Destination":"Sr.Accounts"
}
{
"id":"64542457879",
"Name":"lucifer",
"Sex":"M",
"Destination":"Developer"
}
{
"id":"23824723354",
"Name":"Ratin",
"Sex":"M",
"Destination":"Sr.Developer"
}
當我使用下面的代碼時,我只能打印第一個對象。
val dataframe = spark
.read
.option("multiLine", true)
.schema(Schema)
.json("D:\\appdata\file1")
.show()
您可以使用 spark WholeTextFiles API 讀取漂亮的 jsons 文件
import spark.implicits._
val input = spark.wholeTextFiles(inputFile).map(_._2)
val ouput = input.mapPartitions(records => {
// mapper object created on each executor node (ObjectMapper is not serializable so we either create a singleton object for each partition)
val mapper = new ObjectMapper with ScalaObjectMapper
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
mapper.registerModule(DefaultScalaModule)
records.map(eachitem => {
try {
mapper.readValue(record, classOf[DTOclass])
}catch {
case e: Exception => null
}
})
}).filter(_!=null).toDF.as[DTOclass]
ouput.write.json(oplocation)
您也可以使用 Gson 庫代替 ObjectMapper。
注意:DTOclass 應該是可序列化的
或者您可以清理輸入的漂亮 jsons 文件,並可以通過這里提到的spark.read.json
API 讀取它。
您的文件似乎沒有有效的 Json。 您還可以在https://jsonlint.com/驗證它。 理想情況下,它應該是這樣的
[{
"id":"31342547689",
"Name":"Jacob",
"Sex":"M",
"Destination":"Accounts"
},
{
"id":"987875637898",
"Name":"Martin",
"Sex":"M",
"Destination":"Sr.Accounts"
},
{
"id":"64542457879",
"Name":"lucifer",
"Sex":"M",
"Destination":"Developer"
},
{
"id":"23824723354",
"Name":"Ratin",
"Sex":"M",
"Destination":"Sr.Developer"
}]
所以,首先我們需要預處理這個文件,把它變成一個有效的 Json。
val df=sc.wholeTextFiles("/yourHDFSLocation/file1.json").toDF
df.select("_2").map(s=>"["+s.mkString.replaceAll("\\}.*\n{0,}.*\\{","},{")+"]").repartition(1).write.mode("overwrite").text("/yourHDFSLocation/correctedJson/")
然后我們可以讀取我們的有效 json。
val ok=spark.read.schema(simpleSchema).option("multiline", "true").json("/yourHDFSLocation/correctedJson/p*")
輸出:
ok.show(false)
+------------+-------+---+------------+
|id |Name |Sex|Destination |
+------------+-------+---+------------+
|31342547689 |Jacob |M |Accounts |
|987875637898|Martin |M |Sr.Accounts |
|64542457879 |lucifer|M |Developer |
|23824723354 |Ratin |M |Sr.Developer|
+------------+-------+---+------------+
另一種解決方案,如果您不想保存中間文件。
val rdd=sc.wholeTextFiles("/yourHDFSLocation/file1.json")
val rdd2=rdd.map(s=>"["+s._2.replaceAll("\\}.*\n{0,}.*\\{","},{")+"]")
val ok=spark.read.schema(simpleSchema).option("multiline", "true").json(rdd2)
希望它能解決這個問題!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.