次の 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 の組み合わせごとに複数のレコードが存在する可能性があります。したがって、コードの後半でレコードをグループ化しています。ただし、'location' と 'type' の 2 つの特定の param_names のみに関心があります。
理論的には、'location' の行と 'type' の行が常に存在します。ただし、「タイプ」が存在しない場合があります。したがって、「All」に置き換える必要があります(後で)。
これを行う最も簡単な方法は、データを param_name で分割し、(OUTER) search_id で結合することです。しかし、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, コマーシャル, サンフランシスコ)
これを解決する助けがあれば大歓迎です!