如何将 JSON 拆分为数据集行?
Posted
技术标签:
【中文标题】如何将 JSON 拆分为数据集行?【英文标题】:How to split JSON into Dataset rows? 【发布时间】:2018-12-04 18:17:46 【问题描述】:我有以下 JSON 输入数据:
"lib": [
"id": "a1",
"type": "push",
"icons": [
"iId": "111"
],
"id": "a2",
"type": "pull",
"icons": [
"iId": "111"
,
"iId": "222"
]
]
我想得到以下数据集:
id type iId
a1 push 111
a2 pull 111
a2 pull 222
我该怎么做?
这是我当前的代码。我使用 Spark 2.3 和 Java 1.8:
ds = spark
.read()
.option("multiLine", true).option("mode", "PERMISSIVE")
.json(jsonFilePath);
ds = ds
.select(org.apache.spark.sql.functions.explode(ds.col("lib.icons")).as("icons"));
然而结果是错误的:
+---------------+
| icons|
+---------------+
| [[111]]|
|[[111], [222...|
+---------------+
我怎样才能得到正确的数据集?
更新:
我尝试了这段代码,但它生成了一些额外的 id
、type
和 iId
组合,这些组合在输入文件中不存在。
ds = ds
.withColumn("icons", org.apache.spark.sql.functions.explode(ds.col("lib.icons")))
.withColumn("id", org.apache.spark.sql.functions.explode(ds.col("lib.id")))
.withColumn("type", org.apache.spark.sql.functions.explode(ds.col("lib.type")));
ds = ds.withColumn("its", org.apache.spark.sql.functions.explode(ds.col("icons")));
【问题讨论】:
【参考方案1】:如前所述,JSON 字符串似乎格式不正确。使用更新后,您可以使用以下内容来获得您想要的结果:
import org.apache.spark.sql.functions._
spark.read
.format("json")
.load("in/test.json")
.select(explode($"lib").alias("result"))
.select($"result.id", $"result.type", explode($"result.icons").alias("iId"))
.select($"id", $"type", $"iId.iId")
.show
【讨论】:
我将您的代码应用到@MTCoster 的答案中提供的JSON 文件,并得到以下错误org.apache.spark.sql.AnalysisException: Cannot resolve column name "result.id" among (lib)
另外,如果我将.option("multiLine", true).option("mode", "PERMISSIVE")
添加到 Spark,它只会读取这个 JSON。否则,表明记录已损坏。【参考方案2】:
您的 JSON 格式似乎有误。修正缩进会让这点更明显:
"lib": [
"id": "a1",
"type": "push",
"icons": [
"iId": "111"
],
"id": "a2",
"type": "pull",
"icons": [
"iId": "111"
,
"iId": "222"
]
]
如果您改为输入此 JSON,您的代码是否可以正常工作?
"lib": [
"id": "a1",
"type": "push",
"icons": [
"iId": "111"
]
,
"id": "a2",
"type": "pull",
"icons": [
"iId": "111"
,
"iId": "222"
]
]
注意在"id": "a2"
之前插入的,
以将具有重复键的对象分成两部分,并在最后被省略的关闭。
【讨论】:
以上是关于如何将 JSON 拆分为数据集行?的主要内容,如果未能解决你的问题,请参考以下文章