【问题标题】:Serialize table to nested JSON using Apache Spark使用 Apache Spark 将表序列化为嵌套 JSON
【发布时间】:2018-12-25 03:17:35
【问题描述】:

我有一组类似以下示例的记录

|ACCOUNTNO|VEHICLENUMBER|CUSTOMERID|
+---------+-------------+----------+
| 10003014|    MH43AJ411|  20000000|
| 10003014|    MH43AJ411|  20000001|
| 10003015|   MH12GZ3392|  20000002|

我想解析成 JSON,它应该是这样的:

{
    "ACCOUNTNO":10003014,
    "VEHICLE": [
        { "VEHICLENUMBER":"MH43AJ411", "CUSTOMERID":20000000},
        { "VEHICLENUMBER":"MH43AJ411", "CUSTOMERID":20000001}
    ],
    "ACCOUNTNO":10003015,
    "VEHICLE": [
        { "VEHICLENUMBER":"MH12GZ3392", "CUSTOMERID":20000002}
    ]
}

我已经编写了程序,但未能实现输出。

package com.report.pack1.spark

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql._


object sqltojson {

  def main(args:Array[String]) {
    System.setProperty("hadoop.home.dir", "C:/winutil/")
    val conf = new SparkConf().setAppName("SQLtoJSON").setMaster("local[*]")
    val sc = new SparkContext(conf)
    val sqlContext = new SQLContext(sc)
    import sqlContext.implicits._      
    val jdbcSqlConnStr = "jdbc:sqlserver://192.168.70.88;databaseName=ISSUER;user=bhaskar;password=welcome123;"      
    val jdbcDbTable = "[HISTORY].[TP_CUSTOMER_PREPAIDACCOUNTS]"
    val jdbcDF = sqlContext.read.format("jdbc").options(Map("url" -> jdbcSqlConnStr,"dbtable" -> jdbcDbTable)).load()
    jdbcDF.registerTempTable("tp_customer_account")
    val res01 = sqlContext.sql("SELECT ACCOUNTNO, VEHICLENUMBER, CUSTOMERID FROM tp_customer_account GROUP BY ACCOUNTNO, VEHICLENUMBER, CUSTOMERID ORDER BY ACCOUNTNO ")
    res01.coalesce(1).write.json("D:/res01.json")      
  }
}

如何以给定的格式序列化?提前致谢!

【问题讨论】:

    标签: json scala apache-spark


    【解决方案1】:

    您可以使用structgroupBy 来获得您想要的结果。下面是相同的代码。我已在需要时对代码进行了注释。

    val df = Seq((10003014,"MH43AJ411",20000000),
      (10003014,"MH43AJ411",20000001),
      (10003015,"MH12GZ3392",20000002)
    ).toDF("ACCOUNTNO","VEHICLENUMBER","CUSTOMERID")
    
    df.show
    //output
    //+---------+-------------+----------+
    //|ACCOUNTNO|VEHICLENUMBER|CUSTOMERID|
    //+---------+-------------+----------+
    //| 10003014|    MH43AJ411|  20000000|
    //| 10003014|    MH43AJ411|  20000001|
    //| 10003015|   MH12GZ3392|  20000002|
    //+---------+-------------+----------+
    
    //create a struct column then group by ACCOUNTNO column and finally convert DF to JSON
    df.withColumn("VEHICLE",struct("VEHICLENUMBER","CUSTOMERID")).
      select("VEHICLE","ACCOUNTNO"). //only select reqired columns
      groupBy("ACCOUNTNO"). 
      agg(collect_list("VEHICLE").as("VEHICLE")). //for the same group create a list of vehicles
      toJSON. //convert to json
      show(false)
    
    //output
    //+------------------------------------------------------------------------------------------------------------------------------------------+
    //|value                                                                                                                                     |
    //+------------------------------------------------------------------------------------------------------------------------------------------+
    //|{"ACCOUNTNO":10003014,"VEHICLE":[{"VEHICLENUMBER":"MH43AJ411","CUSTOMERID":20000000},{"VEHICLENUMBER":"MH43AJ411","CUSTOMERID":20000001}]}|
    //|{"ACCOUNTNO":10003015,"VEHICLE":[{"VEHICLENUMBER":"MH12GZ3392","CUSTOMERID":20000002}]}                                                   |
    //+------------------------------------------------------------------------------------------------------------------------------------------+
    

    您也可以使用与您在问题中提到的相同的语句将此dataframe 写入文件。

    【讨论】:

    • 好的。谢谢。但它是这样来的{"value":"{\"ACCOUNTNO\":10003200,\"VEHICLE\":[{\"VEHICLENUMBER\":\"MH04FP4254\",\"CUSTOMERID\":20000287}]}"}
    • 为什么是\字符?第二件事是列表里面很多VEHICLENUMBER没有被合并,因为很多VEHICLENUMBER有重复值。
    • 数据来自远程 SQL Server 中的一个表,当然,一个表包含超过 300 万条记录,是的,它有多个数据。这就是为什么我问你我应该在 GROUPBY 之后添加字段吗?如果是,那么我也会多次获得一辆 VEHICLENUMBER。您在 Stackoverflow 答案中显示的输出结果我想实际获得该结果。是的,该表包含重复数据,所以我应该使用 DISTINCT 之类的东西吗?请帮助我亲爱的朋友。
    • 您使用的数据/表实际上不是我的输入。我猜你已经避开了我的 Scala 代码。我在我的问题中显示的表是远程 SQL Server 中超过 300 万条记录的表的 SQL 查询的结果。为了更好地理解目的,我给出了这张表
    • 你在吗?我需要在列表的字段中使用 groupby。
    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多