如何使用 Spark SQL 在 Parquet 文件中选择嵌套数组和映射

Posted

技术标签:

【中文标题】如何使用 Spark SQL 在 Parquet 文件中选择嵌套数组和映射【英文标题】:How to select nested arrays and maps in a Parquet file using Spark SQL 【发布时间】:2016-12-08 14:53:25 【问题描述】:

我需要在 Parquet 文件中选择深度嵌套的数据结构中的元素。 Parquet 文件的架构如下:

 root
 |-- descriptor_type: string (nullable = true)
 |-- src_date: long (nullable = true)
 |-- downloaded: long (nullable = true)
 |-- exit_nodes: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- fingerprint: string (nullable = true)
 |    |    |-- published: long (nullable = true)
 |    |    |-- last_status: long (nullable = true)
 |    |    |-- exit_adresses: map (nullable = true)
 |    |    |    |-- key: string
 |    |    |    |-- value: long (valueContainsNull = true)

数据集中的一个条目,序列化为 JSON,如下所示:


  "descriptor_type": "tordnsel 1.0",
  "src_date": 1472781720000,
  "downloaded": 1472781720000,
  "exit_nodes": [
    
      "fingerprint": "CECCFA65F3EB16CA8C0F9EAC9050C348515E26C5",
      "published": 1472713568000,
      "last_status": 1472716961000,
      "exit_adresses": 
        "178.217.187.39": 1472717419000
      
    ,
...

我正在使用集成在 SnappyData 0.6 中的 Spark 2.0,其中 Parquet 文件的地址如下:

snappy> CREATE EXTERNAL TABLE stage USING PARQUET OPTIONS (path './testdata.parquet.snappy');

选择第一行会产生以下结果:

snappy> select * from stage limit 1;
descriptor_type|src_date            |downloaded          |exit_nodes                                                                                                                      
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
tordnsel 1.0   |1472781720000       |1472781720000       |5704000060110000e011000060120000d812000058130000d813000058140000d014000050150000d015000050160000d016000048170000c81700004018000&

“exit_nodes”字段仅包含一个长字符串,而不是我天真希望的结构数组。 我可以通过索引选择“exit_nodes”数组中的特定元素:

snappy> select exit_nodes[0].fingerprint, exit_nodes[0].published, exit_nodes[0].exit_adresses from stage limit 1;
EXIT_NODES[0].FINGERPRINT                                   |EXIT_NODES[0].PUBLISHED|EXIT_NODES[0].EXIT_ADRESSES                                                                 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3D28E5FBD0C670C004E59D6CFDE7305BC8948FA8                    |1472750744000          |15000000010000000800000037382e3134322e31392e3231330100000008000000b057f0e656010000  

使用“exit_adresses”地图我没有运气:

snappy> select exit_nodes[0].exit_adresses.key from stage limit 1;
EXIT_NODES[0].EXIT_ADRESSES[KEY]
--------------------------------
NULL    

所以问题是: - 如何在一个“exit_adresses”映射中选择键和值? - 如何选择元素数组中的所有记录,或嵌套映射中的所有键值对,将它们从 Parquet 文件导入到 RDBMS?

【问题讨论】:

【参考方案1】:

我对此没有直接的答案,但恕我直言,除了这个 spark PR-360 之外,没有进一步支持查询嵌套的镶木地板类型

这几乎涵盖了您可以做的所有事情: https://github.com/apache/spark/blob/master/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/parquet/ParquetQuerySuite.scala

【讨论】:

以上是关于如何使用 Spark SQL 在 Parquet 文件中选择嵌套数组和映射的主要内容,如果未能解决你的问题,请参考以下文章

使用 spark 写入 parquet 文件时如何添加额外的元数据

如何在 Spark 2.1.0 中使用 SparkSQL 将“.txt”转换为“.parquet”?

Spark SQL - 如何将 DataFrame 写入文本文件?

Spark Parquet统计(最小/最大)集成

Parquet + Spark SQL

使用 spark sql 重命名 Parquet 文件中列名中的空格