21

Apache Pigを使用して、大きなキー->値のマッピングを作成し、マップで検索して、キーを反復処理したいと思います。ただし、これらのことを行うための構文すら存在しないようです。マニュアル、ウィキ、サンプルコード、エレファントブック、グーグルをチェックし、パーサーソースの解析も試みました。すべての例は、ファイルからマップリテラルをロードします...そしてそれらを使用することはありません。Pigのマップをどのように使用できますか?

まず、2列のCSVファイルをマップに直接ロードする方法はないようです。私が単純なものを持っている場合map.csv

1,2
3,4
5,6

そして、私はそれを地図としてロードしようとします:

m = load 'map.csv' using PigStorage(',') as (M: []);
dump m;

空のタプルが3つあります。

()
()
()

そこで、タプルをロードしてからマップを生成しようとします。

m = load 'map.csv' using PigStorage(',') as (key:chararray, val:chararray);
b = foreach m generate [key#val];
ERROR 1000: Error during parsing. Encountered " "[" "[ "" at line 1, column 24.
...

構文の多くのバリエーションも失敗します(例:)generate [$0#$1]

OK、それで私は自分の地図をPigの地図リテラル形式に次のように変更しますmap.pig

[1#2]
[3#4]
[5#6]

そしてそれをロードします:

m = load 'map.pig' as (M: []);

次に、いくつかのキーをロードして、ルックアップを試してみましょう。

k = load 'keys.csv' as (key);
dump k;
3
5
1

c = foreach k generate m#key;  /* Or m[key], or... what? */
ERROR 1000: Error during parsing.  Invalid alias: m in {M: map[ ]}

うーん、わかりました。おそらく2つの関係があるため、参加する必要があります。

c = join k by key, m by /* ...um, what? */ $0;
dump c;
ERROR 1068: Using Map as key not supported.
c = join k by key, m by m#key;
dump c;
Error 1000: Error during parsing. Invalid alias: m in {M: map[ ]}

失敗。マップのキー(または値)を参照するにはどうすればよいですか?マップスキーマの構文では、キーと値に名前を付けることさえできないようです(メーリングリストには、タイプを割り当てる方法がないと書かれています)。

最後に、マップですべてのキーを見つけられるようにしたいと思います。

d = foreach m generate ...oh, forget it.

Pigのマップタイプは中途半端ですか?私は何が欠けていますか?

4

6 に答える 6

2

現在、pig マップには、文字列を含む変数ではなく、提供する chararray (文字列) へのキーが必要です。そのため、map#key では、キーは指定した定数文字列でなければなりません (例: map#'keyvalue')。

これの典型的な使用例は、要素の 1 つがキーと値のペアである複雑なデータ構造をロードし、後で foreach ステートメントで、関心のあるキーに基づいて特定の値を参照できるようにすることです。

http://pig.apache.org/docs/r0.9.1/basic.html#map-schema

于 2011-11-23T07:30:45.573 に答える
1

Pig バージョン 0.10.0 では、「TOMAP」( http://pig.apache.org/docs/r0.10.0/func.html#tomap )と呼ばれる新しい関数が利用可能になりました。偶数パラメータを値に。残念ながら、私は通常、さまざまな長さとキーの任意の辞書を扱っているため、それほど有用であるとは思いませんでした。

可変数のパラメーターではなく、タプルを単一の引数として取る TOMAP 関数の方がはるかに便利であることがわかります。

これは問題の完全な解決策ではありませんが、TOMAP を使用できるようになったことで、実際の解決策を構築するための選択肢がいくつか増えました。

于 2012-07-30T19:07:24.910 に答える
0

関係の観点から考える必要があると思います。マップは 1 つのレコードの 1 つのフィールドにすぎません。次に、2 つのデータセットの結合やマッピングなど、リレーションにいくつかの操作を適用できます。

入力

$ cat data.txt 
1
2
3
4
5
$ cat mapping.txt 
1   2
2   4
3   6
4   8
5   10

mapping = LOAD 'mapping.txt' AS (key:CHARARRAY, value:CHARARRAY);

data = LOAD 'data.txt' AS (value:CHARARRAY);


-- list keys
mapping_keys =
  FOREACH mapping
  GENERATE key;

DUMP mapping_keys;


-- join mapping to data
mapped_data =
  JOIN mapping BY key, data BY value;

DUMP mapped_data;

出力

> # keys
(1)
(2)
(3)
(4)
(5)

> # mapped data
(1,2,1)
(2,4,2)
(3,6,3)
(4,8,4)
(5,10,5)

この回答は、単純なルックアップを行いたい場合にも役立ちます: pass-a-relation-to-a-pig-udf-when-using-foreach-on-another-relation

于 2010-12-07T18:45:02.927 に答える