簡體   English   中英

在 spark scala 中解析 JSON 對象

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM