【问题标题】:extract json in array in AWS Athena在 AWS Athena 的数组中提取 json
【发布时间】:2020-09-10 03:07:16
【问题描述】:

我已将日志从 kubernetes 发送到 S3 存储桶,并希望使用 Athena 对其进行查询

日志是这样的

[{      "date":1589895855.077230,
      "log":"192.168.85.35 - - [19/May/2020:13:44:15 +0000] \"GET /healthz HTTP/1.1\" 200 3284 \"-\" \"ELB-HealthChecker/2.0\" \"-\"",
      "stream":"stdout",
      "time":"2020-05-19T13:44:15.077230187Z",
      "kubernetes":{
         "pod_name":"myapp-deployment-cd984ffb-kjfbm",
         "namespace_name":"master",
         "pod_id":"eace0175-99cd-11ea-95e4-0aee746ae5d6",
         "labels":{
            "app":"myapp",
            "pod-template-hash":"cd984ffb"
          },
         "annotations":{
            "cluster-autoscaler.kubernetes.io/safe-to-evict":"false",
            "kubernetes.io/psp":"eks.privileged"
          },
         "host":"ip-1-1-1-1.eu-north-1.compute.internal",
         "container_name":"myapp",
         "docker_id":"cb2cda1ed46c5f09d15090fc3f654b1de35970001e366923287cfbd4a4abf4a1"
      }
},
{      "date":1589995860.077230,
      "log":"192.168.1.40 - - [20/May/2020:17:31:00 +0000] \"GET /healthz HTTP/1.1\" 200 3284 \"-\" \"ELB-HealthChecker/2.0\" \"-\"",
      "stream":"stdout",
      "time":"2020-05-20T17:31:00.077230187Z",
      "kubernetes":{
         "pod_name":"myapp-deployment-cd984ffb-kjfbm",
         "namespace_name":"master",
         "pod_id":"eace0175-99cd-11ea-95e4-0aee746ae5d6",
         "labels":{
            "app":"myapp",
            "pod-template-hash":"cd984ffb"
          },
         "annotations":{
            "cluster-autoscaler.kubernetes.io/safe-to-evict":"false",
            "kubernetes.io/psp":"eks.privileged"
          },
         "host":"ip-1-1-1-1.eu-north-1.compute.internal",
         "container_name":"myapp",
         "docker_id":"cb2cda1ed46c5f09d15090fc3f654b1de35970001e366923287cfbd4a4abf4a1"
      }
},]

所以基本上是一个包含 json 对象的数组。

我在 Athena 中使用 CREATE EXTERNAL TABLE 查询来创建表。 我试过的是:

CREATE EXTERNAL TABLE IF NOT EXISTS athenadb.mytable (
                   `data` string
                 )
                 ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
                 LOCATION 's3://mybucket/testlog'
                 TBLPROPERTIES ('has_encrypted_data'='false');

这只会将数组中的第一项读入表中,除非我指定了更多行,例如

data1 字符串

数据2字符串

data3 字符串

但是,由于我不知道数组中有多少项,我需要一些更动态的东西。

然后我尝试了这个

CREATE EXTERNAL TABLE IF NOT EXISTS athenadb.mytable (
                   `data` string
                 )
                 LOCATION 's3://mybucket/testlog'
                 TBLPROPERTIES ('has_encrypted_data'='false');

现在我将整个日志(两个条目)放在表的一行中。

从这里我尝试使用 UNNEST,但出现“无法取消嵌套类型:varchar”的错误

将每个 {} 放入表中自己的行中的最简单方法是什么?也许从 CREATE EXTERNAL TABLE 完成,之后不需要任何额外的查询?

编辑:

现在也试过了

SELECT data
FROM mytable
CROSS JOIN UNNEST(CAST(json_parse(data) AS array)) AS data2

但我得到“未知类型:数组”

我在这里发现了一个类似的问题:How do I import an array of data into separate rows in a hive table?

但似乎没有任何建议的解决方案可以产生想要的结果。

【问题讨论】:

  • 试试CAST(json_parse(data) AS array(json))
  • 使用查询SELECT data FROM mytable CROSS JOIN UNNEST(CAST(json_parse(data) AS array(json)) AS data2 给出错误line 3:57: mismatched input 'as' expecting {'.', ',', ')', '[', 'at', 'or', 'and', 'in', 'not', 'between', 'like', 'is', '=', neq, '<', '<=', '>', '>=', '+', '-', '*', '/', '%', '||'} (service: amazonathena; status code: 400; error code: invalidrequestexception; request id: 609bf5ad-5d87-4eb3-b50d-ddfd9add6024)
  • 这个查询让我更接近了。 SELECT data FROM mytable CROSS JOIN UNNEST(CAST(json_parse(data) AS ARRAY<json>)) 该数组有两个 json 条目,我现在得到两行,但每行包含所有两个 json,而不是每个 json
  • 你找到解决办法了吗?

标签: presto amazon-athena


【解决方案1】:

unnestcasting json to array(json) 结合起来:

SELECT data, e
FROM mytable
CROSS JOIN UNNEST(CAST(json_parse(data) AS array(json))) t(e)

注意:array<json>array(json) 类型定义的旧版本。后者符合 SQL 标准。

【讨论】:

    猜你喜欢
    • 2021-10-18
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 2019-05-05
    • 2021-07-03
    • 2018-08-24
    • 1970-01-01
    相关资源
    最近更新 更多