使用 Spark 访问嵌套在结构中的 json 数组

Posted

技术标签:

【中文标题】使用 Spark 访问嵌套在结构中的 json 数组【英文标题】:Accessing a json array nested in a structure using Spark 【发布时间】:2019-07-06 22:39:59 【问题描述】:

我希望从具有数组的嵌套结构中访问不同的字段/子字段,以便对它们进行算术运算。一些数据实际上在字段名称本身中(我必须访问的结构是这样创建的,对此我无能为力)。特别是,我有一个数字列表作为我必须使用的字段名称,这些数字会从一个 json 文件更改为下一个,因此我必须动态推断这些字段名称是什么,然后将它们与子字段值一起使用。

我看过这个:Access names of fields in struct Spark SQL 不幸的是,我不知道我的结构的字段名称是什么,所以我不能使用它。

我也试过这个,看起来很有希望:how to extract the column name and data type from nested struct type in spark 不幸的是,无论“flatten”函数有什么魔力,我都无法将其调整为字段名而不是字段本身。

这是一个示例 json 数据集。它代表消费篮子:

“comp A”和“comp B”两个篮子中的每一个都有多个价格作为子字段:compA.'55.80' 是价格,compA.'132.88' 是另一个价格,等等。 我希望将这些单价与其各自子字段中的可用数量相关联:compA.'55.80'.comment[0].qty (500) 以及 compA.'55.80'.comment[0].qty (600),都应该与 55.80 相关联。 compA.'132.88'.comment[0].qty (700) 应与 132.88 相关联。等
"type":"test","name":"john doe","products":
    "baskets":
        "comp A":
            "55.80":["type":"fun","comment":"qty":500,"text":"hello","type":"work","comment":"qty":600,"text":"hello"]
            ,"132.88":["type":"fun","comment":"qty":700,"text":"hello"]
            ,"0.03":["type":"fun","comment":"qty":500,"text":"hello","type":"work","comment":"qty":600,"text":"hello"]
        
        ,"comp B":
            "55.70":["type":"fun","comment":"qty":500,"text":"hello","type":"work","comment":"qty":600,"text":"hello"]
            ,"132.98":["type":"fun","comment":"qty":300,"text":"hello","type":"work","comment":"qty":900,"text":"hello"]
            ,"0.01":["type":"fun","comment":"qty":400,"text":"hello"]
        
    

我想在数据框中获取所有这些数字,以便对它们进行一些操作:

+ -------+---------+----------+
+ basket | price   | quantity +
+ -------+---------+----------+
+ comp A | 55.80   | 500      +
+ comp A | 55.80   | 600      +
+ comp A | 132.88  | 700      +
+ comp A | 0.03    | 500      +
+ comp A | 0.03    | 600      +
+ comp B | 55.70   | 500      +
+ comp B | 55.70   | 600      +
+ comp B | 132.98  | 300      +
+ comp B | 132.98  | 900      +
+ comp B | 0.01    | 400      +
+ -------+---------+----------+

原始数据集是这样访问的:

scala> myDs
res135: org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] = [products: struct<baskets: struct<compA: struct<55.80: array<struct .....

【问题讨论】:

我使用以下方法取得了一些进展: spark.read.json(myDs.withColumn("compA",get_json_object($"json","$.products.baskets.compA" )).select("compA").rdd.map(_.getString(0))).columns 这产生: Array[String] = Array(55.80, 132.88, 0.03, .... 这还不够,但是这是一个开始...... ***.com/questions/52525013/… 这应该会给你一些指导。爆炸性需求。 这方面还有什么乐趣吗? 主要困难在于 1. 由于价格发生变化,我事先不知道架构和 2. 价格是字段名称这一事实。除非我弄错了,否则将你与电影相关联的示例因此在这方面没有帮助? 我的那个例子非常简单。您需要了解有关架构的信息。 【参考方案1】:

这种处理以列名形式传入的数据的方法不可遵循。它根本行不通。

【讨论】:

我还没有完全放弃(因为我对数据格式没有权力,而且数据就在那里......)。我会在更新时发布。 对你有好处,但真的很难 yakka。 这个答案表明这是不可能的,但没有说明为什么不可能。实际上,我很确定这是可能的 => 我希望有人(也许是我)找到实际答案并将其发布在此处以记录/帮助他人。 那我期待有一天能得到答案。我注意到这个平台上的专家不止几位,比我好得多,而且迄今为止没有任何回应。 解决了吗?如果是,请发布。

以上是关于使用 Spark 访问嵌套在结构中的 json 数组的主要内容,如果未能解决你的问题,请参考以下文章

如何基于相等性检查在 Spark 中使用内部数组查询嵌套 json

Spark高级操作之json复杂和嵌套数据结构的操作一

如何使用 AWS Glue 从嵌套 json 字段/结构中的 DynamicFrame 访问数据

使 Spark 结构化流中的 JSON 可以在 python (pyspark) 中作为没有 RDD 的数据帧访问

Spark使用DataFrame读取复杂JSON中的嵌套数组

使用 spark 展平嵌套的 json 文档并加载到 Elasticsearch