Pig初学者如何在全球商业数据集中筛选美国城市数据
解决方案:从全球商业数据中过滤出美国城市记录
作为Pig初学者,你已经走对了第一步——加载了两个数据集,接下来我们可以通过关联过滤的方式,只保留属于美国城市的商业数据。下面是一步步的详细操作:
1. 补全美国城市数据集的加载(并规范Schema)
首先得确保us.csv的加载是正确的,假设你的CSV文件里每行是城市,州的格式(比如New York,NY),我们需要明确指定字段类型,方便后续关联:
-- 加载美国城市州数据,指定字段为城市和州(字符串类型) us_citystate = LOAD 'us.csv' USING PigStorage(',') AS (city:chararray, state:chararray);
2. 处理JSON商业数据:提取关键字段
你的raw_bus_data是map[]类型,我们需要先把里面的城市、州字段提取出来(同时保留完整的原始记录,方便最后输出)。另外要注意大小写统一——避免因为New York和new york这种大小写差异导致匹配失败:
-- 从JSON map中提取城市、州,转成小写,同时保留原始完整记录 bus_data_flattened = FOREACH raw_bus_data GENERATE LOWER(row#'city') AS bus_city:chararray, -- 提取商业数据中的城市并转小写 LOWER(row#'state') AS bus_state:chararray, -- 提取商业数据中的州并转小写 row AS full_record; -- 保留原始的完整商业记录
3. 统一美国城市数据的大小写
同样,把美国城市数据的字段也转成小写,保证匹配的一致性:
us_citystate_lower = FOREACH us_citystate GENERATE LOWER(city) AS us_city:chararray, LOWER(state) AS us_state:chararray;
4. 关联过滤:只保留美国城市的商业数据
这里我们用**半连接(Semi-Join)**的思路,只保留商业数据中城市+州能在美国城市数据里找到的记录。因为美国城市数据集通常不大,我们用replicated连接方式(把小表分发到所有节点,提升效率):
-- 关联两个数据集,只保留匹配上的商业记录 us_only_bus_data = JOIN bus_data_flattened BY (bus_city, bus_state), us_citystate_lower BY (us_city, us_state) USING 'replicated';
5. 提取最终的美国商业数据
最后,我们把之前保留的完整原始商业记录提取出来,就是我们要的结果:
final_us_bus_data = FOREACH us_only_bus_data GENERATE full_record; -- 可以把结果存储下来,比如存成JSON STORE final_us_bus_data INTO 'us_business_data' USING com.twitter.elephantbird.pig.store.JsonPigStorage();
额外提醒
- 注意你写的
JsonLoader拼写:应该是com.twitter.elephantbird.pig.load.JsonLoader('-nestedLoad')(你写成了elphantbird,少了个e,这个错误会导致加载失败)。 - 如果你的
us.csv只有城市没有州,那关联的时候只按城市字段即可,但可能会出现重名城市的问题(比如美国有多个叫Springfield的城市),所以最好带上州信息来精准匹配。
内容的提问来源于stack exchange,提问作者StormsEdge
相关产品推荐
相关产品推荐

