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 中将 JSON 转换为 ARRAY<MAP>