【问题标题】:Redshift Spectrum: Query Anonymous JSON array structureRedshift Spectrum:查询匿名 JSON 数组结构
【发布时间】:2019-09-20 12:41:10
【问题描述】:

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

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

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

$[*] 

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

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

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

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

【问题讨论】:

  • 直到今天这仍然是一个问题。除了你在答案中提到的以外,你有没有发现什么?
  • @HasanJ 自从这篇文章以来我所做的所有实现我们都选择每行使用一条记录,而不是[匿名]数组......所以我不知道是否有是否可行的解决方案。

标签: amazon-web-services amazon-redshift aws-glue amazon-redshift-spectrum


【解决方案1】:

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

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

并更新分类器:

$.values[*]

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

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

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

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

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

【讨论】:

    【解决方案2】:

    您可以使用 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

    【讨论】:

      【解决方案3】:

      如果你的表结构如下:

      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

      【讨论】:

        【解决方案4】:

        我已成功完成此操作,但没有数据分类器。我的 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 参数。架构中的前 2 列是什么?您能否在答案中放一个 JSON 示例,以便清楚您的文件是什么样的?感谢您的回答!
        • 我添加了一个示例 JSON。我已经有了上面的架构 - 原始爬虫提出了什么以及我必须如何手动编辑它以使其与 strip.outer.array 参数一起工作。如果还有什么不清楚的地方请告诉我。
        • 我做了同样的事情,但仍然使用了分类器 $[*] 并且它起作用了。这里的关键点是,在手动编辑表格后,请确保再次运行爬虫。这让我可以使用红移光谱查询数据。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-13
        • 2021-01-12
        • 1970-01-01
        • 1970-01-01
        • 2021-03-02
        相关资源
        最近更新 更多