Athena/Presto:复杂结构/数组

Posted

技术标签:

【中文标题】Athena/Presto:复杂结构/数组【英文标题】:Athena/Presto : complex structure/array 【发布时间】:2019-11-25 02:36:41 【问题描述】:

认为我在这里问不可能的事情,但把它扔在那里。 试图在 Athena 中查询一些 json。 我正在处理的数据看起来像这样(摘录)

condition=
        "foranyvalue:stringlike":"s3:prefix":["lala","hehe"],
        "forallvalues:stringlike":"s3:prefix":["apples","bananas"]

.. 我需要到这里:

...另外:键名不固定,所以有一天我可能会得到:

condition="something not seen before":"surprise":["haha","hoho"]

最后一点,我希望将其视为一个数组,并首先将“foranyvalue”和“forallvalues”部分拆分为单独的行。 但由于所有内容都包含在 中,因此它拒绝取消嵌套。

但尽管上述计划失败 - 任何以任何方式解决此问题的提示都非常感激!

谢谢

【问题讨论】:

condition 是列名吗? JSON 是否始终采用 "some_key:with_colon": "some_key": ["array", "of", values"], "some_other_key:with_colon" .... 形式?内部 ... 是否总是只有 1 个条目? Piotr (1)Condition是列名。 (2)"some_key_with_OR_WITHOUT_colon" (3)inner 总是 1 个条目 - 谢谢 .. 抱歉,“值数组”也可能只是一个普通的单个字符串(没有方 [] 括号) 【参考方案1】:

当您的 JSON 数据没有易于描述的架构时,您可以使用 STRING 作为列的类型,然后使用 Athena/Presto 的 JSON functions 来查询它们,并结合转换为 @ 987654323@ 和 UNNEST 以展平结构。

实现我认为您正在尝试做的事情的一种方法是这样的:

WITH the_table AS (
  SELECT CAST(condition AS MAP(VARCHAR, JSON)) AS condition
  FROM (
    VALUES
    (JSON '"foranyvalue:stringlike":"s3:prefix":["lala","hehe"],"forallvalues:stringlike":"s3:prefix":["apples","bananas"]'),
    (JSON '"something not seen before":"surprise":["haha","hoho"]')
  ) AS t (condition)
),
first_flattening AS (
  SELECT 
    SPLIT(first_level_key, ':', 2) AS first_level_key,
    CAST(first_level_value AS MAP(VARCHAR, JSON)) AS first_level_value
  FROM the_table
  CROSS JOIN UNNEST (condition) AS t (first_level_key, first_level_value)
),
second_flattening AS (
  SELECT
    first_level_key,
    second_level_key,
    second_level_value
  FROM first_flattening
  CROSS JOIN UNNEST (first_level_value) AS t (second_level_key, second_level_value)
)
SELECT
 first_level_key[1] AS "for",
 TRY(first_level_key[2]) AS condition,
 second_level_key AS "left",
 second_level_value AS "right"
FROM second_flattening

我在第一个 CTE 中包含了您作为内联 VALUES 列表提供的两个示例,以及在表声明中确切要做的事情(即要使用的列的类型)以及在查询(即演员表)取决于您的数据以及您希望/如何设置表格。 YMMV。

查询通过几个单独的步骤来展平 JSON 结构,首先展平第一级键和值,然后展平内部文档的键和值。或许可以一步完成,但分两步完成至少更易于阅读。

由于第一级键并不总是有冒号,我使用TRY 来确保访问第二个值不会破坏任何内容。您也许可以更早地过滤掉没有冒号的值并避免这种情况,因为您对它们不感兴趣。

【讨论】:

您的回答拯救了我的日子。非常感谢 。请您帮忙准备以下 JSON 数据 ["a":"12","b":"gps","a":"40","b":"stat","a" :"79","b":"第三方"]

以上是关于Athena/Presto:复杂结构/数组的主要内容,如果未能解决你的问题,请参考以下文章

在 Athena/Presto 中将数组拆分为列

在 Athena/Presto 中将 JSON 转换为 ARRAY<MAP>

Athena (Presto) SQL 窗口函数

AWS Athena (Presto) 偏移支持

如何将表示 EPOCH 时间的整数转换为 Athena (Presto) 中的时间戳?

用于 In Query 的 Athena/Presto 拆分字符串