java 将JsonArray转换为Spark Dataset< Row>,无需中间pojo

jgwigjjp  于 2023-04-28  发布在  Java
关注(0)|答案(1)|浏览(201)

从一个http调用中,我收到一个Json,格式如下

{
  "name": "foo",
  "version": 1,
  "uploadDate": "2023-04-17",
  "data": [
    {
      "abc": "123",
      "xyz": "",
      "alpha": "4"
    },
     {
      "abc": "456",
      "xyz": "",
      "alpha": "1"
    },
     {
      "abc": "679",
      "xyz": "",
      "alpha": "2"
    },
     {
      "abc": "890",
      "xyz": "",
      "alpha": "5"
    }
  ]
}

我想提取data元素,将其转换为Dataset<Row>,并将其持久化为一个parquet格式文件。
如果我将这个json命名为String responseBody,我将使用以下命令提取data元素

JsonObject responseBodyObject = new JsonParser().parse(responseBody).getAsJsonObject();
  String dataString = new Gson().toJson(responseBodyObject.get("data"));

对我来说,再次让字符串对象到字符串似乎有点浪费。我这样做是因为我将把它提供给spark.read().json(string)
我的最终目标是将data转换为具有以下结构的Spark Dataset<Row>

| abc | xyz | alpha |
---------------------
| 123 |     | 4     |
| 456 |     | 1     |
| 679 |     | 2     |
| 890 |     | 5     |

有没有可能在不创建与json列表中的对象匹配的POJO对象的情况下实现这一点?我可以只使用JsonElement或JsonArray吗?我宁愿避免为每个http端点创建一个新类型(不想每次端点更改结构时都更改该代码,因为那一边的油漆还没有完全干燥),并且我将立即将该Dataset写入一个parquet文件,无论如何,我不会对这些数据进行任何操作。所以我觉得像Row这样的模糊类型就足够了。
我不是很熟悉Spark,你会怎么做呢?
编辑:语法+一点关于为什么我不想要POJO的额外信息

9rygscc1

9rygscc11#

所以我试图通过加载JSON数据来解决(Scala语言)

val df = spark.read.format("json").option("multiline","True").load("path")
df.show()

that data will be show as dataset
but you can explode the data in familiar. so
val df1 = df.withColumn("data",explode($"data")).select("data.*","name","version","uploadDate) 
df1.show()

输出将如下所示

+---+-----+---+----+----------+-------+
|abc|alpha|xyz|name|uploadDate|version|
+---+-----+---+----+----------+-------+
|123|    4|   | foo|2023-04-17|      1|
|456|    1|   | foo|2023-04-17|      1|
|679|    2|   | foo|2023-04-17|      1|
|890|    5|   | foo|2023-04-17|      1|
+---+-----+---+----+----------+-------+

如果你不想添加额外的列,你可以修改代码,如

val df1 = df.withColumn("data",explode($"data")).select("data.*") 
    df1.show()

输出将如您所愿

+---+-----+---+
|abc|alpha|xyz|
+---+-----+---+
|123|    4|   |
|456|    1|   |
|679|    2|   |
|890|    5|   |
+---+-----+---+

在Java语言中通过

import static org.apache.spark.sql.functions.*;

// Assuming the input DataFrame is named "df"
DataFrame df1 = df.withColumn("data", explode(col("data")))
                  .select("data.*");
df1.show();

相关问题