亚马逊雅典娜 - 嵌套的JSON问题

时间:2017-09-21 18:38:33

标签: json multidimensional-array hive hiveql amazon-athena

我有以下json对象供一个人参加会议:

    {"conferences_attended": [
            {"conference_name": "dreamforce",
            "date": "2017",
            "city": "san francisco",
            "state": "ca"},
            {"conference_name": "RampUp",
            "date": "2016",
            "city": "san francisco",
            "state": "ca"},
            ],
    "last_name" : "doe"}

我运行了以下代码来创建表,指向我在s3

中存储数据的位置
    CREATE EXTERNAL TABLE IF NOT EXISTS my_db.attendees (
      `last_name` string,
      `conferences_attended` array< struct<
          conference_name:string,
          date:string,
          city:string,
          state:string,
        >>,
    )
    ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
    WITH SERDEPROPERTIES (
      'serialization.format' = '1'
    ) LOCATION 's3://**'
    TBLPROPERTIES ('has_encrypted_data'='false');

现在,我的问题分为两部分。

1)如何查询访问嵌套json对象中的数据?下面的两个查询不起作用,也没有很多类似的查询。

    SELECT conferences_attended
    FROM attendees;

    SELECT conferences_attended.conference_name
    FROM attendees;

2)如何查询返回仅匹配嵌套json的特定部分的结果?

    SELECT *
    FROM attendees
    WHERE conferences_attended.conference_name like '%force%';

我收到错误导致我相信我需要更改数据类型或取消嵌套数据或类似的东西...感谢帮助和指向支持这些类型操作的信息的链接。请注意,我已阅读以下链接并发现它们有用,但仍未解决我的需求。 http://docs.aws.amazon.com/athena/latest/ug/rows-and-structs.htmlhttp://thornydev.blogspot.com/2013/07/querying-json-records-via-hive.html以及其他许多人......

最后,有关org.apache.hive.hcatalog.data.JsonSerDe&#39;之间差异的任何建议或资源。和&#39; org.openx.data.jsonserde.JsonSerDe&#39;欢迎。

1 个答案:

答案 0 :(得分:0)

首先,外部表中的字段与您尝试将其指向的json文件中的字段不匹配。

看起来,您的表定义应如下所示:

CREATE EXTERNAL TABLE IF NOT EXISTS my_db.attendees (
  `last_name` string,
  `conferences_attended` array<struct<conference_name:string,
    date:string, city:string, state:string>>,
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '1'
) LOCATION 's3://**'
TBLPROPERTIES ('has_encrypted_data'='false');

您在尝试访问其他字段时提到了company_name和linkedin_company_id作为meetings_attended字段。

在此之后,您可以通过以下方式访问字段:

SELECT conferences_attended
FROM attendees;

但是,由于meetings_attended是一个结构数组,因此您需要提及数组索引来访问该特定数组结构的字段。所以不要这样:

SELECT conferences_attended.conference_name
FROM attendees;

尝试这样的事情:

SELECT conferences_attended[1].conference_name FROM attendees;

现在,如果要解析数组中的所有结构并对数据应用一些过滤器,可以使用UNNEST函数以下列方式执行此操作:

SELECT 
last_name, 
conferences.conference_name, 
conferences.date, 
conferences.city, 
conferences.state 
FROM 
attendees CROSS JOIN UNNEST(conferences_attended) as t(conferences) 
WHERE 
conferences.conference_name like '%force%';

您可以参考以下链接以获取更多参考: http://docs.aws.amazon.com/athena/latest/ug/flattening-arrays.html