1

次のような行があります。

evnt=redeem&lid=1030023&upt=1679&pid=000000000001076056,000000000001072654,000000000001067925&ppt=996,246,366&qty=1,2,3

蓋、pid、ppt、および数量を行から抽出し、pid、ppt、および数量のすべてのエントリのタプルを作成することに興味があります。ルールは次のとおりです。

  • ふた以外はすべて複数の値を持つことができます。値にカンマがある場合、複数の値があります
  • pid は複数の値を持つことができ、これらの値は他の値と同じ順序で関連付けられます。たとえば、 ifとthen 、およびifとthenをlid=4&pid=1,2&qty=2,3&ppt=123,232意味します。lid=4pid=1qty=2ppt=123lid=4pid=2qty=3ppt=232
  • ppt は、pid に相関するという点で qty と同じ規則に従います。

これらのフィールドの蓋とpidに対して、次のようにしてこれを達成できました。

logs = foreach logs generate
                    REGEX_EXTRACT(original_path, 'lid=([^&]+)', 1) as login_id,
                    FLATTEN(TOKENIZE(REPLACE(REGEX_EXTRACT(original_path, '.*pid=([^&]+)', 1), ',', ' '))) as pid;

これは私に与えます:

1030023    000000000001076056
1030023    000000000001072654
1030023    000000000001067925

ただし、他の 2 つのフィールドに対してもこれを行いたい (3 つのタプルのままにしておく) ため、同じ foreach ステートメントで複数のフラット化を行っても、必要なものが得られません。

1030023    000000000001076056    996    1
1030023    000000000001072654    246    2
1030023    000000000001067925    366    3

これにはUDFが必要になると思いますが、Pigで提供されている関数のみを使用して別の方法があるかどうかを知りたい.

4

1 に答える 1

1

出力をどの程度正確にしたいのか少しわかりませんが、これは純粋な豚でこれを行う方法です。

私の意見では、フィールドの数がわからない場合、タプルは pig では少し厄介です。したがって、数字の順序が問題にならない場合は、バッグを使用することをお勧めします. この場合、TOKENIZE は出力をバッグとして作成し、STRSPLIT は出力をタプルとして作成します。

このコード:

A = LOAD 'logs' AS (total:chararray);                                   
B = FOREACH A {  
    -- In this case a nested foreach makes the code much easier to read.                                                            
    lid = REGEX_EXTRACT(total, 'lid=([^&]+)', 1) ;
    -- TOKENIZE splits on ',' creating a bag.
    pid = TOKENIZE(REGEX_EXTRACT(total, '.*pid=([^&]+)', 1), ',') ;
    -- STRSPLIT splits on ',' creating a tuple.
    ppt = STRSPLIT(REGEX_EXTRACT(total, '.*ppt=([^&]+)', 1), ',') ;             
    qty = STRSPLIT(REGEX_EXTRACT(total, '.*qty=([^&]+)', 1), ',') ;             
    GENERATE lid as lid, FLATTEN(pid) as pid, ppt as ppts, qty as qtys ;         
}  

このスキーマと出力を生成します。

B: {lid: chararray,pid: chararray,ppts: (),qtys: ()}
(1030023,000000000001076056,(996,246,366),(1,1,1))
(1030023,000000000001072654,(996,246,366),(1,1,1))
(1030023,000000000001067925,(996,246,366),(1,1,1))

タプルの代わりに TOKENIZE を使用してバッグを作成すると、次の出力が作成されます。

B: {lid: chararray,pid: chararray,ppts: {tuple_of_tokens: (token: chararray)},qtys: {tuple_of_tokens: (token: chararray)}}
(1030023,000000000001076056,{(996),(246),(366)},{(1),(1),(1)})
(1030023,000000000001072654,{(996),(246),(366)},{(1),(1),(1)})
(1030023,000000000001067925,{(996),(246),(366)},{(1),(1),(1)})

pid もタプルにしたい場合は、次の 2 行を変更するだけです。

pid = TOKENIZE(REGEX_EXTRACT(total, '.*pid=([^&]+)', 1), ',') ;   
GENERATE lid as lid, FLATTEN(pid) as pid, ppt as ppts, qty as qtys ; 

に:

pid = STRSPLIT(REGEX_EXTRACT(total, '.*pid=([^&]+)', 1), ',') ;   
GENERATE lid as lid, pid as pid, ppt as ppts, qty as qtys ; 
于 2013-07-01T16:04:33.700 に答える