【问题标题】:Java Spark: How to get value from a column which is JSON formatted string for entire dataset?Java Spark:如何从整个数据集的 JSON 格式字符串的列中获取值?
【发布时间】:2021-04-01 18:26:33
【问题描述】:

这里需要一些帮助。我正在尝试从 Hive/CSV 读取数据。有一列,其类型为字符串,值为 json 格式的字符串。是这样的:

|                      Column Name A                       |
|----------------------------------------------------------|
|"{"key":{"data":{"key_1":{"key_A":[123]},"key_2":[456]}}}"|

如何获取 key_2 的值并将其插入新列?

我尝试创建一个新函数来通过 Gson 获取值

private BigDecimal getValue(final String columnValue){
    JsonObject jsonObject = JsonParser.parseString(columnValue).getAsJsonOBject();
    return jsonObject.get("key").getAsJsonObject().get("key_1").getAsJsonObject().get("key_2").getAsJsonArray().get(0).getAsBigDecimal();
}

但是我如何将这种方法应用于整个数据集?

我试图实现这样的目标:

Dataset<Row> ds = souceDataSet.withColumn("New_column", getValue(sourceDataSet.col("Column Name A")));

但由于数据类型不同,无法做到……

您可以给点建议吗?

谢谢! 哈哈!

------------------更新----------

正如@Mck 所建议的,我使用了 get_json_object。 因为我的值包含"

"{"key":{"data":{"key_1":{"key_A":[123]},"key_2":[456]}}}"

我使用子字符串删除了" 并制作了这样的新字符串

{"key":{"data":{"key_1":{"key_A":[123]},"key_2":[456]}}}

子字符串的代码

DataSet<Row> dsA = sourceDataSet.withColumn("Column Name A",expr("substring(Column Name A, 2, length(Column Name A))"))

我使用了dsA.show() 并确认数据集看起来正确。

然后我用下面的代码尝试做到这一点

Dataset<Row> ds = dsA.withColumn("New_column",get_json_object(dsA.col("Column Name A"), "$.key.data.key_2[0]"));

返回null

但是,如果数据是这样的:

{"key":{"data":{"key_2":[456]}}}

我可以得到值 456。

任何建议为什么我会得到空值? 谢谢帮忙!

【问题讨论】:

    标签: java json apache-spark apache-spark-sql


    【解决方案1】:

    使用get_json_object:

    ds.withColumn(
        "New_column",
        get_json_object(
            col("Column Name A").substr(lit(2), length(col("Column Name A")) - 2),
            "$.key.data.key_2[0]")
    ).show(false)
    
    +----------------------------------------------------------+----------+
    |Column Name A                                             |New_column|
    +----------------------------------------------------------+----------+
    |"{"key":{"data":{"key_1":{"key_A":[123]},"key_2":[456]}}}"|456       |
    +----------------------------------------------------------+----------+
    

    【讨论】:

    • 嗨,麦克,谢谢您的帮助!正如你所建议的,我使用了 get_json_object。但是,它为我返回 null 。如果我从字符串中删除了 key_1 及其值,它就可以工作。有什么建议?我已经更新了原来的问题。
    • @Lehtia 你能显示你用来删除引号的代码吗?只是想确保正确完成
    • @Lehtia 我包含了一个使用 substr 的代码 - 看看这是否适合你?
    • 嗨@mck,我已经更新了原始问题。我使用 expr 来获取子字符串。并使用 dataset.show() 确认它已被删除。谢谢!
    • @Lehtia 显然,只有开头的引号被删除,但结尾的引号仍然存在。然后 json 查询失败,因为 json 字符串格式错误。我觉得应该是length(Column Name A) -1
    猜你喜欢
    • 2020-02-29
    • 1970-01-01
    • 2020-03-17
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 2016-10-10
    • 2022-07-12
    相关资源
    最近更新 更多