在 Pig 中解析复杂的嵌套 JSON

Posted

技术标签:

【中文标题】在 Pig 中解析复杂的嵌套 JSON【英文标题】:Parsing complex nested JSON in Pig 【发布时间】:2016-11-12 19:47:00 【问题描述】:

我想将 Billionaires JSON 数据集解析成 Pig。可以在 here 找到 JSON 文件。

以下是每个条目的内容:


    "wealth": 
        "worth in billions": 1.2,
        "how": 
             "category": "Resource Related",
             "from emerging": true,
             "industry": "Mining and metals",
             "was political": false,
             "inherited": true,
             "was founder": true
         ,
         "type": "privatized and resources"
    ,
    "company": 
        "sector": "aluminum",
        "founded": 1993,
        "type": "privatization",
        "name": "Guangdong Dongyangguang Aluminum",
        "relationship": "owner"
        ,
    "rank": 1372,
    "location": 
          "gdp": 0.0,
          "region": "East Asia",
          "citizenship": "China",
          "country code": "CHN"
              ,
    "year": 2014,
    "demographics": 
              "gender": "male",
              "age": 50
              ,
    "name": "Zhang Zhongneng"

尝试 1

我尝试在 grunt 中使用以下命令加载此数据:

billionaires = LOAD 'billionaires.json' USING JsonLoader('wealth: (价值数十亿:double,如何:(类别:chararray,来自 新兴:chararray,行业:chararray,政治:chararray, 继承:chararray,创始人:chararray),类型:chararray),公司: (sector:chararray,founded:int,type:chararray,name:chararray,relationship:chararray),rank:int,location:(gdp:double,region:chararray,citizenship:chararray,country 代码:chararray),年份:int,人口统计:(性别:chararray,年龄:int), 名称:chararray');

然而,这给了我错误:

错误 org.apache.pig.tools.grunt.Grunt - 错误 1200:不匹配的输入 'in' 期望 RIGHT_PAREN

尝试 2

接下来我尝试使用 Twitter 的大象鸟项目的加载程序,名为 com.twitter.elephantbird.pig.load.JsonLoader。 Here 是此 UDF 的代码。这就是我所做的:

billionaires = LOAD 'billionaires.json' USING com.twitter.elephantbird.pig.load.JsonLoader('-nestedLoad') AS (json:map[]);
names = foreach billionaires generate json#'name' AS name;
dump names;

现在它运行了,我没有收到任何错误!但是什么都没有显示。我得到如下输出:

输入:成功读取 0 条记录(1445335 字节): “hdfs://localhost:9000/user/purak/billionaires.json”

输出:成功将 0 条记录存储在: "hdfs://localhost:9000/tmp/temp-1399280624/tmp-477607570"

计数器:写入的总记录数:0 写入的总字节数:0 可溢出 内存管理器溢出计数:0 主动溢出的包总数:0 总计 主动泄露的记录:0

工作 DAG:job_1478889184960_0005

我在这里做错了什么?

【问题讨论】:

【参考方案1】:

这可能不是最好的方法,但这就是我最终要做的:

    从字段名称中删除空格:我在 json 数据集中用“worth_in_billions”、“from_emerging”等替换了“十亿价值”、“来自新兴”等字段。 (我为此做了一个简单的“查找和替换”)

    逗号分隔的 json 到换行符分隔的 json:我拥有的 json 文件的格式为 ["_comment":"first entry" ...,"_comment":"second entry" ...]。但是 Pig 中的 JsonLoader 将每个换行符作为一个新条目。为了使 json 文件用换行符而不是逗号分隔,我使用了js,它是一个命令行 JSON 处理器。使用sudo apt-get install js 安装它并运行cat billionaires.json | jq -c ".[]" > newBillionaires.json

    newBillionaires.json 文件现在每个条目都在新行上。现在将此文件加载到 Pig 中:

    copyFromLocal /home/purak/Desktop/newBillionaires.json /user/purak

亿万富翁 = 加载 'newBillionaires.json' 使用 JsonLoader('name:chararray, 人口统计: (年龄:int,性别:chararray),年份:int,位置:(country_code:chararray,citizenship:chararray,地区:chararray,gdp:double),rank:int,公司: (关系:chararray,名称:chararray,类型:chararray,founded:int,sector:chararray), 财富:(类型:chararray,如何:(was_创始人:chararray,继承:chararray,was_political:chararray,行业:chararray, from_emerging:chararray,category:chararray),worth_in_biilions:double)');

注意:使用 js 颠倒了每个条目中的字段顺序。因此,在加载命令中,与问题中的加载命令相比,所有字段的顺序都是相反的。

    您现在可以使用以下方法取消嵌套每个元组:

billionairesFinal = foreach 亿万富翁生成名字, 人口统计.age 作为年龄,人口统计.gender 作为性别,年份, location.country_code 为 countryCode,location.citizenship 为 公民身份,location.region 作为地区,location.gdp 作为 gdp,排名, company.relationship as companyRelationship, company.name as companyName, company.type as companyType, company.founded 为 companyFounded, company.sector 为 companySector, 财富类型为 财富类型,财富.how.was_founder as wasFounder,财富.how.inherited 作为继承,weather.how.was_political 和 wasPolitical, 财富.how.industry 作为行业,财富.how.from_emerging 作为 fromEmerging, 财富.how.category 为类别, 财富.worth_in_biilions 为worthInBillions;

    使用describe billionairesFinal;检查结构一次:

billionairesFinal: name: chararray,age: int,gender: chararray,year: 整数,国家代码:chararray,公民身份:chararray,地区: chararray,gdp: double,rank: int,companyRelationship: 字符数组,公司名称:字符数组,公司类型: chararray,companyFounded: int,companySector: chararray,wealthType: chararray,是创始人:chararray,继承:chararray,是政治: chararray,行业:chararray,来自新兴:chararray,类别: chararray,worthInBillions: double

这就是我在 Pig 中想要的数据结构!现在我可以继续分析数据集了:)

【讨论】:

以上是关于在 Pig 中解析复杂的嵌套 JSON的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中解析嵌套的复杂 JSON 响应

如何在java中解析复杂的嵌套JSON?

使用 Pig 在 XPath 中进行嵌套解析

无法使用 Pig 中的 Elephant Bird 访问带有包和元组的嵌套 JSON

Flink SQL 解析复杂(嵌套)JSON

android使用gson解析嵌套复杂的json数据,数据怎么显示到布局上,布局怎么写