相关文章推荐
卖萌的眼镜  ·  飞猪 - 开放平台·  9 月前    · 
刚毅的卤蛋  ·  html c++ ...·  1 年前    · 

Redshift Spectrum:查询匿名JSON数组结构

3 人关注

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

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

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

然而,当试图从Spectrum查询时,它返回。

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

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

是否不可能通过Spectrum查询匿名数组?

2 个评论
直到今天,这仍然是一个问题。除了你在答案中提到的内容外,你还发现了其他问题吗?
@HasanJ 从这个帖子开始,我所做的所有实现都选择了每行使用一条记录,而不是一个[匿名]数组......所以我不知道是否有一个可行的解决方案。
amazon-web-services
amazon-redshift
aws-glue
amazon-redshift-spectrum
comfytoday
comfytoday
发布于 2019-05-02
4 个回答
comfytoday
comfytoday
发布于 2020-06-15
0 人赞同

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

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

并更新分类器。

$.values[*]

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

最后,这个解决方案并不奏效,因为Spectrum从未真正返回任何结果。没有错误,只是没有结果,到现在为止,除了每行使用单个记录外,仍然没有其他解决办法。

{"key":"value"}
{"key":"value"}

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

我很想知道是否有其他人能让它工作......

MargaretT
MargaretT
发布于 2020-06-15
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;
    
@HassanJ 我不知道我的答案对你和@comfytoday是否有效
这是个有趣的解决方案。我没有见过 strip.out.array 这个参数。模式中的前两列是什么?你能在你的答案中放一个JSON的例子吗,这样就能清楚你的文件是什么样子的?谢谢你的回答!
我添加了一个JSON的例子。我已经有了上面的模式--原始爬虫得出的结果,以及我不得不手动编辑它以使其与strip.outer.array参数一起工作。如果还有不清楚的地方,请告诉我。
我做了同样的事情,但仍然使用了分类器 $[*] ,结果成功了。这里的关键点是,在手动编辑你的表格后,确保你再次运行爬虫。这让我用红移谱查询数据。
这个解决方案对我有用,但我的json的格式和OP一样。我唯一需要做的是按照这里的描述更新爬虫配置,并手动将 strip.outer.array 添加到表的属性中,并将其设置为 true
Ajay Pant
Ajay Pant
发布于 2020-06-15
0 人赞同

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

对于第二个索引元素 select json_extract_array_element_text('[111,112,113]', 2);

输出。113

Ajay Pant
Ajay Pant
发布于 2020-06-15
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;