Spark - 如何将 JSON 转义的字符串字段解析为 DataFrames 中的 JSON 对象?
Posted
技术标签:
【中文标题】Spark - 如何将 JSON 转义的字符串字段解析为 DataFrames 中的 JSON 对象?【英文标题】:Spark - How to parse a JSON-escaped String field as a JSON Object in DataFrames? 【发布时间】:2017-06-23 19:10:44 【问题描述】:我有一组文件作为输入,每行格式化为一个 JSON 对象。然而,问题在于这些 JSON 对象上的一个字段是 JSON 转义字符串。示例
"clientAttributes":"backfillId":null,"clientPrimaryKey":"abc","escapedJsonPayload":"\"name\":\"Akash\",\"surname\":\"Patel\",\"items\":[\"itemId\":\"abc\",\"itemName\":\"xyz\""
当我通过读取 json 文件创建数据框时,它正在创建如下数据框
val df = spark.sqlContext.read.json("file:///home/akaspate/sample.json")
df: org.apache.spark.sql.DataFrame = [clientAttributes: struct<backfillId: string, clientPrimaryKey: string>, escapedJsonPayload: string]
我们可以看到“escapedJsonPayload
”是字符串,我需要它是结构。
注意:我在 *** 中遇到了类似的问题并关注了它 (How to let Spark parse a JSON-escaped String field as a JSON Object to infer the proper structure in DataFrames?) 但它给了我“[_corrupt_record: string]”
我已经尝试了以下步骤
val df = spark.sqlContext.read.json("file:///home/akaspate/sample.json") (Work file)
val escapedJsons: RDD[String] = sc.parallelize(Seq("""df"""))
val unescapedJsons: RDD[String] = escapedJsons.map(_.replace("\"", "").replace("\"", "").replace("\\\"", "\""))
val dfJsons: DataFrame = spark.sqlContext.read.json(unescapedJsons) (This results in [_corrupt_record: string])
任何帮助将不胜感激
【问题讨论】:
【参考方案1】:首先,您提供的 JSON 格式错误(语法上)。修正后的 JSON 如下:
"clientAttributes":"backfillId":null,"clientPrimaryKey":"abc","escapedJsonPayload":\"name\":\"Akash\",\"surname\":\"Patel\",\"items\":[\"itemId\":\"abc\",\"itemName\":\"xyz\"]
接下来,要从上述 JSON 中正确解析 JSON,您必须使用以下代码:
val rdd = spark.read.textFile("file:///home/akaspate/sample.json").toJSON.map(value => value.replace("\\", "").replace("\"value\":\"", "").replace("\"", "")).rdd
val df = spark.read.json(rdd)
上面的代码会给你以下输出:
df.show(false)
+----------------+-------------------------------------+
|clientAttributes|escapedJsonPayload |
+----------------+-------------------------------------+
|[null,abc] |[WrappedArray([abc,xyz]),Akash,Patel]|
+----------------+-------------------------------------+
使用以下架构:
df.printSchema
root
|-- clientAttributes: struct (nullable = true)
| |-- backfillId: string (nullable = true)
| |-- clientPrimaryKey: string (nullable = true)
|-- escapedJsonPayload: struct (nullable = true)
| |-- items: array (nullable = true)
| | |-- element: struct (containsNull = true)
| | | |-- itemId: string (nullable = true)
| | | |-- itemName: string (nullable = true)
| |-- name: string (nullable = true)
| |-- surname: string (nullable = true)
我希望这会有所帮助!
【讨论】:
感谢 himanshuIIITian@ 详细解答。关于“首先您提供的 JSON 格式错误(语法上)”,我们无法控制此输入文件,并且我们从上游服务获取此格式。所以它看起来像这样“escapedJsonPayload”:“\”name\”:\“Akash\””。你能告诉我们如何在 Spark 中处理这个问题吗? 简单...只需在 JSON 值上应用replace("\\", "")
。就像我在回答中提到的那样。
@AkashPatel 请接受答案或提供反馈。
接受了答案。感谢您的帮助以上是关于Spark - 如何将 JSON 转义的字符串字段解析为 DataFrames 中的 JSON 对象?的主要内容,如果未能解决你的问题,请参考以下文章
如何将字符串中带有双引号的json文件加载到spark scala中的数据框中
如何在Spark SQL中查询StringType的1个字段具有json值的数据框