在 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的主要内容,如果未能解决你的问题,请参考以下文章