1

次の 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, コマーシャル, サンフランシスコ)

これを解決する助けがあれば大歓迎です!

4

1 に答える 1