如何在Pig中加载包含外部值的JSON数据?
解决Elephant Bird JsonLoader加载ID+JSON混合格式数据的问题
你的问题核心在于Elephant Bird的JsonLoader默认会把整行内容当作完整合法的JSON来解析,但你的每行数据是ID,JSON这种逗号分隔的混合格式——开头的ID会让整行变成非标准JSON结构,自然加载失败。下面是具体的解决思路和可运行的脚本:
步骤1:拆分ID与JSON字符串
先用Pig原生的PigStorage按逗号拆分每行数据,把独立的ID字段和JSON字符串分开:
REGISTER json-simple-1.1.1.jar; REGISTER elephant-bird-pig-4.3.jar; REGISTER elephant-bird-hadoop-compat-4.3.jar; -- 按逗号拆分,提取ID和原始JSON字符串 raw_data = LOAD 'ek.json' USING PigStorage(',') AS (id:chararray, json_str:chararray);
这里ID用chararray是因为你的示例ID是带前导零的000000,如果用int会丢失前导零,可根据实际业务需求调整类型。
步骤2:解析JSON字符串为结构化数据
接下来用Elephant Bird提供的JsonStringToMap UDF,把JSON字符串解析成Pig可操作的Map结构,再按需提取字段:
-- 将JSON字符串解析为Map格式 parsed_json = FOREACH raw_data GENERATE id, com.twitter.elephantbird.pig.piggybank.JsonStringToMap(json_str) AS json_map; -- 从Map中提取指定字段,转换成你需要的Tuple结构 final_data = FOREACH parsed_json GENERATE id, json_map#'000'#'phoneNumber' AS phoneNumber:chararray, json_map#'000'#'firstName' AS firstName:chararray, json_map#'000'#'lastName' AS lastName:chararray, json_map#'000'#'email' AS email:chararray, json_map#'000'#'alternatePickup' AS alternatePickup:boolean, json_map#'000'#'sendTextNotification' AS sendTextNotification:boolean, json_map#'000'#'isSendTextNotification' AS isSendTextNotification:boolean, json_map#'000'#'isAlternatePickup' AS isAlternatePickup:boolean; DUMP final_data;
备选方案:构造合法JSON后再加载
如果你更习惯用JsonLoader的方式,也可以先把ID和JSON拼接成一个完整的JSON对象,再用JsonLoader解析(但这种方式需要处理字符串拼接细节,不如第一种方法稳妥):
raw_data = LOAD 'ek.json' USING PigStorage(',') AS (id:chararray, json_str:chararray); -- 拼接成合法的JSON对象:{"id":"000000","000":{...}} formatted_json = FOREACH raw_data GENERATE CONCAT('{"id":"', id, '",', SUBSTRING(json_str, 1, SIZE(json_str)-1), '}') AS full_json; -- 用JsonLoader解析完整JSON json_data = LOAD formatted_json USING com.twitter.elephantbird.pig.load.JsonLoader() AS (id:chararray, json_key: (phoneNumber:chararray, firstName:chararray, lastName:chararray, email:chararray, alternatePickup:boolean, sendTextNotification:boolean, isSendTextNotification:boolean, isAlternatePickup:boolean)); DUMP json_data;
内容的提问来源于stack exchange,提问作者Bhagwan S Soni
相关产品推荐
相关产品推荐

