如何将 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...|
+---------------+

我怎样才能得到正确的数据集?

更新:

我尝试了这段代码,但它生成了一些额外的 idtypeiId 组合,这些组合在输入文件中不存在。

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 拆分为数据集行?的主要内容,如果未能解决你的问题,请参考以下文章

使用javascript将json数据集值拆分为数据表

将非特定数量的数据集行添加到列表中

如何将结果集行作为索引子数组添加到结果数组中?

如何获取数据集行的特定版本?

oracle 结果集行转列,多行数据转为一行显示,第一列内容拼接生成字段名

跨数据集行的数组元素总和 - Spark Scala