在 Spark SQL 中将结构转换为映射

bot*_*que 6 apache-spark apache-spark-sql

我正在尝试将声明一列具有某种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
Run Code Online (Sandbox Code Playgroud)

预期输出是一列类型map<string, string>

struct_col:map<字符串, 字符串>
{"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
Run Code Online (Sandbox Code Playgroud)

bot*_*que 9

to_json我找到了一种方法来做到这一点,需要使用和函数来序列化和解析 json 一次往返from_json。诀窍是,from_json在我使用该类型的地方,它还带有一个模式参数map<string, string>

此外,此解决方案应该适用于 Spark < 3.x

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;
Run Code Online (Sandbox Code Playgroud)