2

我在 S3 中有一个 JSON 结构数组,它被 Glue 成功抓取和编目。

[{"key":"value"}, {"key":"value"}]

我正在使用自定义分类器:

$[*] 

但是,当尝试从 Spectrum 查询时,它会返回:

当且仅当设置了 serde 属性“strip.outer.array”时,顶级 Ion/JSON 结构必须是匿名数组。文件中出现不匹配...

我在 Glue 目录表中手动设置了该 serde 属性,但没有任何改变。

不能通过 Spectrum 查询匿名数组吗?

4

4 回答 4

2

像这样在 JSON 文件中命名数组:

"values":[{"key":"value"},...}

并更新分类器:

$.values[*]

修复了这个问题...有兴趣知道是否有办法查询匿名数组。像这样存储数据似乎很常见。

更新:最后这个解决方案不起作用,因为 Spectrum 永远不会真正返回任何结果。没有错误,只是没有结果,到目前为止,除了每行使用单独的记录之外,仍然没有解决方案:

{"key":"value"}
{"key":"value"}
etc.

这似乎是 Spectrum 特定的问题,因为 Athena 仍然可以工作。

有兴趣知道是否有其他人能够让它工作......

于 2019-05-02T02:39:53.977 回答
1

您可以使用 json_extract_path_text 提取元素或 json_extract_array_element_text('json string', pos [, null_if_invalid ] )。

例如:对于第二个索引元素选择 json_extract_array_element_text('[111,112,113]', 2);

输出:113

于 2020-06-14T11:58:01.853 回答
0

如果你的表结构如下:

CREATE EXTERNAL TABLE spectrum.testjson(struct<id:varchar(25), 
columnName<array<struct<key:varchar(20),value:varchar(20)>>>);

您可以使用以下查询来访问数组元素:

SELECT c.id, o.key, o.value FROM   spectrum.testjson c, c.columnName o;

有关更多信息,您可以参考 AWS 文档:

https://docs.aws.amazon.com/redshift/latest/dg/tutorial-query-nested-data-sqlextensions.html

于 2020-06-14T11:50:37.247 回答
0

我已经成功地做到了这一点,但没有数据分类器。我的 JSON 文件如下所示:

[
    {
        "col1": "data_from_col1",
        "col2": "data_from_col2",
        "col3": [
            {
                "col4": "data_from_col4",
                ...
            {
        ]
    },
    {
        "col1": "data_from_col1",
        "col2": "data_from_col2",
        "col3": [
            {
                "col4": "data_from_col4",
                ...
            {
        ]
    },
    ...
]

我开始使用爬虫来获取基本的表定义。重要提示:不能将输出下的爬虫配置选项设置为更新表定义...,否则稍后重新运行爬虫将覆盖下面描述的手动更改。我只使用了添加新列。

我必须添加“strip.outer.array”属性并在我的匿名数组中手动​​添加最顶层的列。初始爬虫运行的原始架构是:

anon_array array<struct<col1:string,col2:string,col3:array<struct<col4...>>>
partition_0 string

我手动将我的架构更新为:

col1:string
col2:string
col3:array<struct<col4...>>
partition_0 string

(并且还要添加 serde 参数 strip.outer.array。)

然后我不得不重新运行我的爬虫,最后我可以像这样在 Spectrum 中查询:

select o.partition_0, o.col1, o.col2, t.col4
from db.tablename o
LEFT JOIN o.col3 t on true;
于 2020-10-27T12:22:03.143 回答