1

Apache Pig バージョン 0.10.1.21 (reported) の使用

データサンプルファイルの内容:

AtomicNumber,ElementName,Symbol,AtomicMass,PropertyMap
46,Palladium,Pd,106.42,[P#46,N#60,Struc#Cubic]
49,Indium,In,114.818,[P#49,N#66,Struc#Tetragonal]
52,Tellurium,Te,127.6,[P#52,N#76,Struc#Hexagonal]
86,Radon,222.0,Rn,[P#86,N#136,Struc#Cubic]
38,Strontium,Sr,87.62,[P#38,N#50,Struc#Cubic]
Plutonium,94,Pu,244.0,[P#94,N#150,Struc#Monoclinic]

注: Pig がデータ型の不一致をどのように処理するかを確認するために、一部の列が意図的に交換されています (Radon と Plutonium の場合)。

豚のスクリプト:

AtomElem = LOAD 'data/Atoms.txt' USING PigStorage(',') AS (AtomicNumber:int, ElementName:chararray, Symbol:chararray, AtomicMass:float, PropertyMap:map[]);
DUMP AtomElem;

結果:

(,ElementName,Symbol,,)
(46,Palladium,Pd,106.42,)
(49,Indium,In,114.818,)
(52,Tellurium,Te,127.6,)
(86,Radon,222.0,,)
(38,Strontium,Sr,87.62,)
(,94,Pu,244.0,)

質問1 : PropertyMap が表示されることを期待していました。PropertyMap 列をマップ データ型として表示するために、豚のスクリプトまたはデータ ファイルを変更する方法を教えてください。

質問2 : マップ スキーマの宣言で、データ型を厳密に型指定したいと考えています。スキーマを PropertyMap:map[int, int, chararray] として宣言しましたが、pig は構文を拒否しました ( のエラー、右括弧が予想されます)。複数のキーを持つマップを宣言することは可能ですか? はいの場合、スキーマ宣言はどのようになりますか?

助けてくれてありがとう。

4

2 に答える 2

1

スクリプトがマップを正常に生成しない理由は、フィールドの区切り記号としてコンマを使用しているためですが、これはマップのキーと値のペアの区切り記号でもあります。そのため、Pig が行をフィールドに分割すると、5 番目のフィールドは[P#46,N#60,Struc#Cubic]予想どおり ではなく、 になります[P#46。Pig はこれをマップとして正常に解析できないため、 に変換されNULLます。

2 番目の質問については、個々のマップ値のデータ型を指定することはできません。そもそも、地図では順序は意味がありません。また、マップには任意の数の要素を含めることができます。すべての値に対して単一のデータ型を指定したい場合は、それを行うことができますが、それを超えると、Pig がその型を判断するか、使用時に値を明示的にキャストする必要があります。

これらの両方のポイントを説明するために、入力データをタブ区切りに変更し (それに応じてスクリプトを に更新しましたUSING PigStorage('\t'))、2 行目の 2 つのマップ要素の位置を入れ替えて、Pig がそれらの順序を再現しないことを示しました。で提供されました。

$ cat data.txt
AtomicNumber    ElementName     Symbol  AtomicMass      PropertyMap
46      Palladium       Pd      106.42  [P#46,N#60,Struc#Cubic]
49      Indium  In      114.818 [N#66,Struc#Tetragonal,P#49]
52      Tellurium       Te      127.6   [P#52,N#76,Struc#Hexagonal]
86      Radon   222.0   Rn      [P#86,N#136,Struc#Cubic]
38      Strontium       Sr      87.62   [P#38,N#50,Struc#Cubic]
Plutonium       94      Pu      244.0   [P#94,N#150,Struc#Monoclinic]

$ cat test.pig
AtomElem = LOAD 'data.txt' USING PigStorage('\t') AS (AtomicNumber:int, ElementName:chararray, Symbol:chararray, AtomicMass:float, PropertyMap:map[]);
DUMP AtomElem;

$ pig -x local test.pig
(,ElementName,Symbol,,)
(46,Palladium,Pd,106.42,[P#46,N#60,Struc#Cubic])
(49,Indium,In,114.818,[P#49,N#66,Struc#Tetragonal])
(52,Tellurium,Te,127.6,[P#52,N#76,Struc#Hexagonal])
(86,Radon,222.0,,[P#86,N#136,Struc#Cubic])
(38,Strontium,Sr,87.62,[P#38,N#50,Struc#Cubic])
(,94,Pu,244.0,[P#94,N#150,Struc#Monoclinic])
于 2013-05-09T21:24:16.917 に答える
0

個人的には、すべてのデータを JSON として保存し、そこからロードします。ロードされたデータセットに複雑なデータ構造がある場合、JSON はマップなどをロードするよりもネストされた構造のはるかに単純な標準であるため、後でこれに取り組む人にとって管理がはるかに簡単になります。豚。

@WinnieNicklausの答えもうまくいくはずですが、これに取り組んでいる次の人、または次に複雑なものをデータに追加する必要がある場合、同じ問題に遭遇します。すべてを JSON に保存し、Pig のビルトイン JSON ローダーでロードするだけです。

a = load 'a.json' using 
JsonLoader('a0:int,a1:{(a10:int,a11:chararray)},a2:(a20:double,a21:bytearray),a3:[chararray]');

スキーマを提供したくない場合は、ElephantBird の JSON ローダーを使用してロードすることもできます。

loaded = LOAD '/path/to/some_file.json'
    using com.twitter.elephantbird.pig.load.JsonLoader('-nestedLoad');

私の記憶が正しければ、どちらも .gz ファイルで問題なく動作するはずです。また、エレファントバード バージョンは lzos でも動作します。

于 2013-05-09T21:34:28.170 に答える