有效 select pyspark 中的键值镶木地板列

Efficiently select key value parquet column in pyspark

我正在处理相当大的镶木地板 table,并且 99.9% 的数据包含在单个 key:value 列中。例如:

# Cannot use hive metastore to access so we have to load this way
df = spark.read.parquet('hdfs://cluster/path/to/parquet') \
    .select('id, 'version', 'details')
df.printSchema()
>> root
 |-- id: string
 |-- version: string
 |-- details: map
 |    |-- key: string
 |    |-- value: struct
 |    |    |-- complex_struct_1: struct
 |    |    |    |-- complex_substruct_1: struct
 |    |    |    |    |-- ...
 |    |    |    |-- ...
 |    |    |-- complex_struct_2: struct
 |    |    |    |-- complex_substruct_n: struct
 |    |    |    |    |-- ...
 |    |    |    |-- ...
 |    |    |-- complex_field_n: struct

有问题的列是 details,可能的键是 key_1key_2、两者或 none。我的问题是如何才能有效地 select 仅属于 key_1 的子字段(例如 select details['key_1'].complex_struct_1.complex_substruct_1.field)?

因为 table 不在 hive metastore 中,我不相信我可以在这里使用 spark.sql,否则会有任何好处。我了解如何天真地加载数据库,select 整个详细信息列然后进行过滤,但考虑到详细信息列绝对庞大(数千个字段)并且我只想要一个小子集,我想利用如果可能,请在此处进行柱状访问。这是我可以更有效地做的事情,还是超出了 parquet 的能力?

您可以通过创建临时视图来使用 Spark SQL:

df.createOrReplaceTempView('df')
df2 = spark.sql("""select details['key_1'].complex_struct_1.complex_substruct_1.field from df""")

这应该是高效的,并且应该只获取您需要的结果子集。您可以执行 df2.explain() 查看查询的实际执行情况。