请考虑以下PIG数据:
search_values = FOREACH raw_search GENERATE
search_id,
user_id,
param_name,
param_value;
describe search_values;
search_values: {search_id: int,user_id: int,param_name: chararray,param_value: chararray}
dump search_values;
(1, 1, location, San Francisco)
(1, 1, type, Commercial)
每个search_id / user_id组合可能有多条记录;因此,我稍后会在代码中对记录进行分组。但是,我只对两个特定的param_names感兴趣 - ' location'和'键入': filtered = FILTER search_values by(param_name ==' type'或param_name ==' location');
理论上,总有一排有“位置”的位置。和一行'类型&#39 ;;但是,有些情况下' type'不在这里;因此,我需要用' All'替换它。 (后)。
我知道最简单的方法是通过param_name拆分数据然后通过search_id(OUTER)连接;但是,我想在PIG中利用袋子的力量。
我尝试了各种使用行李的方法,将行李转换为地图无济于事:
maps = FOREACH filtered GENERATE search_id, user_id, TOMAP(param_name, param_value) as tomap_values;
group_map = group maps by (search_id, user_id);
grouped = FOREACH group_map GENERATE
group.$0 as search_id,
group.$1 as user_id,
maps.tomap_values as map_bag;
这里的问题是map_bag是一个包内的地图,我无法使用map_bag#' type'从中提取值。或map_bag#' location'。
describe grouped:
{search_id: int,user_id: int,map_bag: {(tomap_values: map[])}}
如果我尝试以下内容,我收到错误消息:
mapped = FOREACH grouped
GENERATE
search_id,
user_id,
map_bag.tomap_values#'type',
map_bag.tomap_values#'location';
ERROR 1052: Cannot cast bag with schema :bag{:tuple(tomap_values:map)} to map with schema :map
理想的结果应该是
(search_id,user_id,type,location)
(1,1,商业,旧金山)
任何帮助解决这个问题将不胜感激!
答案 0 :(得分:0)
尝试使用FLATTEN将地图从包中取出。