在 Scala / Spark 中将 JSON 结构解析为 JSON 对象

Posted

技术标签:

【中文标题】在 Scala / Spark 中将 JSON 结构解析为 JSON 对象【英文标题】:Parse a JSON struct as a JSON object in Scala / Spark 【发布时间】:2020-03-16 16:56:15 【问题描述】:

我在我的 MongoDB 集合中存储了大量 JSON 字符串。为简单起见,我将一个示例文档提取到文本文件businessResource.json


   "data" : 
        "someBusinessData" : 
            "capacity" : 
                "fuelCapacity" : NumberLong(282)
            ,
            "someField" : NumberLong(16),
            "anotherField" : 
                "isImportant" : true,
                "lastDateAndTime" : "2008-01-01T11:11",
                "specialFlag" : "YMA"
            ,
   ...

我的问题:如何使用 Spark/Scala 将“someBusinessData”转换为 JSON 对象?

如果我这样做(例如使用 json4s 或 lift-json),我希望我可以对它们执行基本操作,例如检查它们是否相等。

请记住,这是一个相当大的 JSON 对象。在我的案例中创建一个案例类是不值得的,因为我将执行的唯一操作将是对两个字段进行一些过滤,比较文档是否相等,然后我将再次导出它们。

这就是我获取数据的方式:

 val df: DataFrame = (someSparkSession).sqlContext.read.json("src/test/resources/businessResource.json")

 val myData: DataFrame = df.select("data.someBusinessData")
 myData.printSchema

架构显示:

root
 |-- someBusinessData: struct (nullable = true)
 |    |-- capacity: struct (nullable = true)

由于“someBusinessData”是一个结构,我无法将其作为字符串获取。当我尝试使用打印时 myData.first.getStruct(0),我得到一个包含值但不包含键的字符串:[[[282],16,[true,2008-01-01T11:11,YMA]

感谢您的帮助!

【问题讨论】:

【参考方案1】:

不要使用.json,而是使用.textFile来读取您的json文件。

然后我们将rdd 转换为dataframe(将只有一个字符串列)。

Example:

//read json file as textfile and create df

val df=spark.sparkContext.textFile("<json_file_path>").toDF("str")

//use get_json_object function to traverse json string
df.selectExpr("""get_json_object(str,"$.data.someBusinessData")""").show(false)

//+-----------------------------------------------------------------------------------------------------------------------------------------------------+
//|get_json_object(str,$.data.someBusinessData)                                                                                                         |
//+-----------------------------------------------------------------------------------------------------------------------------------------------------+
//|"capacity":"fuelCapacity":"(282)","someField":"(16)","anotherField":"isImportant":true,"lastDateAndTime":"2008-01-01T11:11","specialFlag":"YMA"|
//+-----------------------------------------------------------------------------------------------------------------------------------------------------+

【讨论】:

您是否暗示我必须安装 Apache Hive?不能用 Spark / Scala / json4s / lift-web json 代替吗? 答案是否符合您的要求?并且无需安装 hive,我们使用的是 spark-scala! 我很快尝试使用它。 “get_json_object”的导入和/或 sbt 依赖项是什么?顺便说一句,不是我对你投了反对票:) 让我们继续聊天:chat.***.com/rooms/209779/…【参考方案2】:

其实我的帖子有两个问题:

    如何使用 Spark/Scala 将“someBusinessData”转换为 JSON 对象? 如何将 JSON 对象作为字符串获取?

1.转换成 JSON 对象

我所做的是已经创建了一个可以作为 JSON 对象导航的 DataFrame:

//read json file as Json and select the needed data
val df: DataFrame = sparkSession.sqlContext.read.json(filePath).select("data.someBusinessData")

如果您执行.textFile,则您正确获得了字符串,但解析 JSON,则您需要求助于 Shu 的答案。

2。如何将 JSON 对象作为字符串获取?

琐碎:

    df.toJSON.first

【讨论】:

以上是关于在 Scala / Spark 中将 JSON 结构解析为 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

在scala中将spark决策树模型调试字符串转换为嵌套JSON

如何读取 CSV 文件,然后在 Spark Scala 中将其保存为 JSON?

在 Spark-Scala 中将单个字符串列拆分为多列

在scala中将Spark Dataframe转换为RDD

如何在 Scala 中将 Spark DataFrames 一一添加到 Seq()

在 IntelliJ IDE 中将 Spark 与 Scala 项目集成时出错