在 Spark SQL 中将结构转换为映射
Posted
技术标签:
【中文标题】在 Spark SQL 中将结构转换为映射【英文标题】:Convert struct to map in Spark SQL 【发布时间】:2022-01-19 14:45:30 【问题描述】:我正在尝试将一个声明一列以具有特定struct
类型(例如struct<x: string, y: string>
)的数据集转换为map<string, string>
类型。我想用 SQL 来做,可能不使用 UDF。
更新:
我的要求也是在没有任何结构键先验知识的情况下进行一般转换(在我的问题中,我正在获取复杂 JSON 中的数据,并且我不想在架构中保留这种复杂性)。
输入数据示例:
WITH input (struct_col) as (
select named_struct('x', 'valX', 'y', 'valY') union all
select named_struct('x', 'valX1', 'y', 'valY2')
)
select *
from input
预期输出是map<string, string>
类型的列
struct_col:map<string, string> |
---|
"x":"valX","y":"valY" |
"x":"valX1","y":"valY2" |
更新:
到目前为止,我设法找到了这个非常复杂的解决方案,它只适用于 Spark >= 3.1.0
(因为 json_object_keys
函数)。能够将结构转换为地图真是太好了
WITH input (struct_col) as (
select named_struct('x', 'valX', 'y', 'valY') union all
select named_struct('x', 'valX1', 'y', 'valY2')
)
select transform_values(
map_from_arrays(
json_object_keys(to_json(struct_col)),
json_object_keys(to_json(struct_col))
),
(k, v) -> get_json_object(to_json(struct_col), '$.' || k))
from input
【问题讨论】:
【参考方案1】:我找到了一种方法,它需要使用to_json
和from_json
函数来回序列化和解析一个json。诀窍是 from_json
还接受一个架构参数,我使用 map<string, string>
类型。
此外,此解决方案应适用于 spark
WITH input (struct_col) as (
select named_struct('x', 'valX', 'y', 'valY')
union all
select named_struct('x', 'valX1', 'y', 'valY2')
)
select from_json(to_json(struct_col), 'map<string, string>') as map_col
from input;
【讨论】:
【参考方案2】:怎么样
create_map('struct_col.x', 'struct_col.valX', 'struct_col.y', 'struct_col.valY')
【讨论】:
感谢您的回答。也许我没有在问题中提到这一点,但我的意思是一个任意的,可能是巨大的结构。我试图通过使用地图来消除复杂性并明确列出字段和值不是一种选择。 您能否将其添加到问题中。你如何区分地图和关键列?有后缀吗? 我更新了问题(谢谢)。你是什么意思_你如何区分地图和关键列_?我不明白这个问题。 你有很多列的结构,你想组成一个键值对,你介意它们配对的顺序吗?如果是的话是什么 我不会依赖地图输入顺序 - 他们甚至保留顺序吗?就像在 hashmap 中一样,我只会按键获取元素或以任意顺序遍历整个地图。以上是关于在 Spark SQL 中将结构转换为映射的主要内容,如果未能解决你的问题,请参考以下文章
将 SQL 查询转换为 Spark Dataframe 结构化数据处理
如何在pyspark中将rdd行转换为带有json结构的数据框?