我已从AWS S3中加载的客户端接收到数据集。数据包含未命名的JSON key:value对。这不是我的专业领域,因此我正在寻找一点帮助。
过去我通常使用的JSON数据的结构类似于以下内容:
{ "name":"John", "age":30, "car":null }
我从客户端收到的数据的格式如下:
{
"answer_id": "cc006",
"answer": {
"101086": 1,
"101087": 2,
"101089": 2,
"101090": 7,
"101091": 5,
"101092": 3,
"101125": 2
}
}
[这是调查数据,其中左侧的键是数字客户标识,而右侧的值是他们对调查问题的答复,即,客户“ 101125”以“ 2”的值回答了调查。我需要能够使用Athena查询JSON数据,以使我的结果集类似于:
将未嵌套的子节点与父节点交叉连接不是问题。我不知道的是如何在不指定实际键名的情况下从数组“答案”中选择所有键。同样,我也希望能够选择所有值。
是否有可能在Athena中创建一个虚拟表以允许这些结果,或者我是否需要将JSON转换为看起来更类似于以下内容的格式:
{
"answer_id": "cc006",
"answer": [
{ "key": "101086", "value": 1 },
{ "key": "101087", "value": 2 },
{ "key": "101089", "value": 2 },
{ "key": "101090", "value": 7 },
{ "key": "101091", "value": 5 },
{ "key": "101092", "value": 3 },
{ "key": "101125", "value": 2 }
]
}
EDIT 6/4/2020
我能够使用Theon下面提供的代码以及以下表结构:
CREATE EXTERNAL TABLE answer_example (
answer_id string,
answer string
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://mybucket/'
这使我可以使用以下查询来生成所需的结果。
WITH Data AS(
SELECT
answer_id,
CAST(json_extract(answer, '$') AS MAP(VARCHAR, VARCHAR)) as answer
FROM
answer_example
)
SELECT
answer_id,
key,
element_at(answer, key) AS value
FROM
Data
CROSS JOIN UNNEST (map_keys(answer)) AS answer (key)
EDIT 6/5/2020
从下面的Theon响应中获取其他建议,以下DDL和Query对此进行了相当大的简化。
DDL:
CREATE EXTERNAL TABLE answer_example (
answer_id string,
answer map<string,string>
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://mybucket/'
查询:
SELECT
answer_id,
key,
element_at(answer, key) AS value
FROM
answer_example
CROSS JOIN UNNEST (map_keys(answer)) AS answer (key)
与answer
属性的键交叉连接,然后选择相应的值。像这样的东西:
WITH data AS (
SELECT
'cc006' AS answer_id,
MAP(
ARRAY['101086', '101087', '101089', '101090', '101091', '101092', '101125'],
ARRAY[1, 2, 2, 7, 5, 3, 2]
) AS answers
)
SELECT
answer_id,
key,
element_at(answers, key) AS value
FROM data
CROSS JOIN UNNEST (map_keys(answers)) AS answer (key)
您可能可以用transform_keys
做一些操作来创建键值对的行,但是上面的SQL可以解决问题。