10分でHadoop-Pigの基本文法を理解する
Hadoop MapReduce デザインパターン ―MapReduceによる大規模テキストデータ処理
- 作者: Jimmy Lin,Chris Dyer,神林飛志,野村直之,玉川竜司
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/10/01
- メディア: 大型本
- 購入: 4人 クリック: 254回
- この商品を含むブログ (16件) を見る
はじめに
年末から使い続けているPigについて勉強した事をまとめていきます。主に以下のDocumentを参照しています。PigのDocumentでLatinを日本語で詳しく紹介しているものが見当たらなかったので、そういった目的でこの記事を参照されている方のお役に立てれば光栄です。
Pig Tutorial
tutorial.tar.gzのdownloadとscriptの実行
tutorialのサンプルファイルが入っているtutorial.tar.gzをdownloadして解凍します。解凍したら作成されるディレクトリに移動します。試しにlocalmodeでscript1-local.pigを実行してみます。実行すると結果のディレクトリがlocalに作成されて中身を確認する事ができます。実行したサンプルはexecite-small.logという検索Queryログをtab区切りでparseして、Queryのngramを抽出します。抽出したngramの頻度に対してscoreを付けて、頻度の高いngramを出力しています。では以下では文法を確認して行きます。
$ wget -O tutorial.tar.gz "https://cwiki.apache.org/confluence/download/attachments/27822259/pigtutorial.tar.gz?version=1&modificationDate=1311188529000" $ tar xzf tutorial.tar.gz $ cd pigtmp $ ls -rw-r--r--. 1 yuta yuta 204K 7月 21 04:01 2011 excite-small.log -rw-r--r--. 1 yuta yuta 10M 7月 21 04:01 2011 excite.log.bz2 -rw-r--r--. 1 yuta yuta 11M 7月 21 04:01 2011 pig.jar -rw-r--r--. 1 yuta yuta 3.8K 7月 21 04:01 2011 script1-hadoop.pig -rw-r--r--. 1 yuta yuta 3.8K 7月 21 04:01 2011 script1-local.pig -rw-r--r--. 1 yuta yuta 3.5K 7月 21 04:01 2011 script2-hadoop.pig -rw-r--r--. 1 yuta yuta 3.4K 7月 21 04:01 2011 script2-local.pig -rw-r--r--. 1 yuta yuta 11K 7月 21 04:01 2011 tutorial.jar $ pig -x local script1-local.pig 2013-01-05 03:32:08,341 [main] INFO org.apache.pig.Main - Logging error messages to: /home/yuta/scripts/pigtmp/pig_1357324328284.log 2013-01-05 03:32:08,621 [main] INFO org.apache.pig.backend.hadoop.executionengine.HExecutionEngine - Connecting to hadoop file system at: file:/// 2013-01-05 03:32:09,203 [main] WARN org.apache.pig.PigServer - Encountered Warning USING_OVERLOADED_FUNCTION 3 time(s). 2013-01-05 03:32:09,205 [main] INFO org.apache.pig.tools.pigstats.ScriptState - Pig features used in the script: GROUP_BY,ORDER_BY,DISTINCT,FILTER (略) $ cat script1-local-results/part-r-00000 07 new 2.4494897427831788 2 1.1428571428571426 08 pictures 2.04939015319192 3 1.4999999999999998 08 computer 2.4494897427831788 2 1.1428571428571426 08 s 2.545584412271571 3 1.3636363636363635 10 free 2.2657896674010605 4 1.923076923076923 10 to 2.6457513110645903 2 1.125 10 pics 2.794002794004192 3 1.3076923076923075 10 school 2.828427124746189 2 1.1111111111111114 11 pictures 2.04939015319192 3 1.4999999999999998 11 in 2.1572774865200244 3 1.4285714285714284 13 the 3.1309398305840723 6 1.9375 14 music 2.1105794120443453 4 1.6666666666666667 14 city 2.2360679774997902 2 1.1666666666666665 14 university 2.412090756622109 3 1.4000000000000001 15 adult 2.8284271247461903 2 1.1111111111111112 17 chat 2.9104275004359965 3 1.2857142857142854 19 in 2.1572774865200244 3 1.4285714285714284 19 car 2.23606797749979 3 1.3333333333333333データ型について
Pig Latin Basics
Pigで扱うデータ型をLOAD時(後で説明)に定義する事ができます。以下はPigのデータ型ですので、よく覚えておくと良いと思います。
Simple Types
データ型 意味 例 int 符号付き32Bit整数 10 long 符号付き64Bit整数 Data:10L or 10l Display:10L float 32bit浮動小数点型 Data:10.5F or 10.5f or 10.5e2f or 10.5E2F Display: 10.5F or 1050.0F double 64bit浮動小数点型 Data:10.5 or 10.5e2 or 10.5E2 Display: 10.5 or 1050.0 chararray UTF-8形式のstring(character array) hello world bytearray blob型のデータ binary boolean boolean true / false Complex Types
データ型 意味 例 tuple データ項目の組み合わせ (19,2) bag tupleの組み合わせ {(19,2), (18,1)} map 辞書データ。key/value [open#apache] ※ tuple,bag,fieldという単語が良く出てきますが、関係はbag > tuple > fieldというものになっている事をイメージしてもらえれば問題ないと思います。
PigScriptからUDFを使うためにはREGISTERで登録する
PigScriptからorg.apache.pig.tutorial.NonURLDetector(query)のような不要なqueryを除外するような独自に定義した関数郡のjarファイルを登録するためにはREGISTERを使います。ちなみにtutorial.jarにはNonURLDetector以外にも以下のようなclassファイルが含まれています。またソースコードもhadoop-pigパッケージに含まれているので確認することができます。
REGISTER ./tutorial.jar; raw = LOAD 'excite-small.log' USING PigStorage('\t') AS (user, time, query); clean1 = FILTER raw BY org.apache.pig.tutorial.NonURLDetector(query);$ zipinfo tutorial.jar Archive: tutorial.jar Zip file size: 10725 bytes, number of entries: 13 drwxr-xr-x 2.0 unx 0 bx stor 11-Jul-20 12:01 META-INF/ -rw-r--r-- 2.0 unx 107 b- defN 11-Jul-20 12:01 META-INF/MANIFEST.MF drwxr-xr-x 2.0 unx 0 b- stor 11-Jul-20 12:01 org/ drwxr-xr-x 2.0 unx 0 b- stor 11-Jul-20 12:01 org/apache/ drwxr-xr-x 2.0 unx 0 b- stor 11-Jul-20 12:01 org/apache/pig/ drwxr-xr-x 2.0 unx 0 b- stor 11-Jul-20 12:01 org/apache/pig/tutorial/ -rw-r--r-- 2.0 unx 2201 b- defN 11-Jul-20 12:01 org/apache/pig/tutorial/ExtractHour.class -rw-r--r-- 2.0 unx 3283 b- defN 11-Jul-20 12:01 org/apache/pig/tutorial/NGramGenerator.class -rw-r--r-- 2.0 unx 2302 b- defN 11-Jul-20 12:01 org/apache/pig/tutorial/NonURLDetector.class -rw-r--r-- 2.0 unx 3728 b- defN 11-Jul-20 12:01 org/apache/pig/tutorial/ScoreGenerator.class -rw-r--r-- 2.0 unx 2163 b- defN 11-Jul-20 12:01 org/apache/pig/tutorial/ToLower.class -rw-r--r-- 2.0 unx 4044 b- defN 11-Jul-20 12:01 org/apache/pig/tutorial/TutorialTest.class -rw-r--r-- 2.0 unx 1114 b- defN 11-Jul-20 12:01 org/apache/pig/tutorial/TutorialUtil.class 13 files, 18942 bytes uncompressed, 8953 bytes compressed: 52.7%$ repoquery -l hadoop-pig | grep NonURLDetector /usr/share/doc/pig-0.8.1+28.39/examples/src/org/apache/pig/tutorial/NonURLDetector.java $ cat /usr/share/doc/pig-0.8.1+28.39/examples/src/org/apache/pig/tutorial/NonURLDetector.java package org.apache.pig.tutorial; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.List; import java.util.ArrayList; import org.apache.pig.FilterFunc; import org.apache.pig.FuncSpec; import org.apache.pig.data.Tuple; import org.apache.pig.impl.logicalLayer.schema.Schema; import org.apache.pig.data.DataType; import org.apache.pig.impl.logicalLayer.FrontendException; /** * This function removes search queries that are URLs (as defined by _urlPattern). * This function also removes empty queries. */ public class NonURLDetector extends FilterFunc { private Pattern _urlPattern = Pattern.compile("^[\"]?(http[:|;])|(https[:|;])|(www\\.)"); public Boolean exec(Tuple arg0) throws IOException { if (arg0 == null || arg0.size() == 0) return false; String query; try{ query = (String)arg0.get(0); if(query == null) return false; query = query.trim(); }catch(Exception e){ System.err.println("NonURLDetector: failed to process input; error - " + e.getMessage()); return false; } if (query.equals("")) { return false; } Matcher m = _urlPattern.matcher(query); if (m.find()) { return false; } return true; } /* (non-Javadoc) * @see org.apache.pig.EvalFunc#getArgToFuncMapping() * This is needed to make sure that both bytearrays and chararrays can be passed as arguments */ @Override public List<FuncSpec> getArgToFuncMapping() throws FrontendException { List<FuncSpec> funcList = new ArrayList<FuncSpec>(); funcList.add(new FuncSpec(this.getClass().getName(), new Schema(new Schema.FieldSchema(null, DataType.CHARARRAY)))); return funcList; } }LOADでデータの読み込み、USINGでデータParserを指定、ASで変数としてのデータをaliasで定義
今回Queryの元データ集計を行うためのファイルは以下のようなタブ区切りでデータが保存されています。まずはデータを読み込むためにLOAD 'ファイル名'でデータを呼び出します。呼び出したデータをパースしてカラム変数に格納するためにUSINGとASを使います。PigStorage関数の引数にparseするためのdelimiterを入れます。tutorialの例では'\t'と入れていますが、defaultは'\t'なので入れなくても動きます。PigStorageClassについては以下のリンク先を参照すると良いと思います。PigStorage (Pig 0.10.0 API) ASはdelimiterによって分離されたデータ項目をカラム順に格納します。ASを使わないということも出来ます。カラムのaliasを持たない場合は$0,$1,$2のように$とカラム番号名で参照することになります。ASの中ではデータ型の定義が可能です。user:chararrayのように指定します。chararrayは上で説明した文字列型の事です。
2A9EABFB35F5B954 970916105432 +md foods +proteins BED75271605EBD0C 970916001949 yahoo chat BED75271605EBD0C 970916001954 yahoo chat BED75271605EBD0C 970916003523 yahoo chat BED75271605EBD0C 970916011322 yahoo search BED75271605EBD0C 970916011404 yahoo chat BED75271605EBD0C 970916011422 yahoo chat BED75271605EBD0C 970916012756 yahoo cahtraw = LOAD 'excite-small.log' USING PigStorage('\t') AS (user, time, query); raw = LOAD 'excite-small.log' USING PigStorage('\t') -- カラム名を指定しないので参照する時は$0,$1,$2 raw = LOAD 'excite-small.log' USING PigStorage('\t') AS (user: chararray, time: chararray, query: chararray); -- データ型を指定格納されているデータを確認する場合はDUMPを利用する
格納されている変数のデータを確認するにはDUMPを利用します。単純にDUMP 変数名;として指定するだけです。DUMPはLOAD、FILTER、FOREACHなどによって生成された結果の変数に対してはデータの出力が可能ですが、DUMP 変数名.ASカラム名;といった指定で特定のカラムのみを出力することができません。
DUMP raw; -- DUMP raw.user -- 失敗する例(0158F8ACC570947D,970916162130,wu tang clan) (0158F8ACC570947D,970916162623,doggumentary) (0158F8ACC570947D,970916163639,control machete) (06878125BE78B42C,970916183900,how to make ecstacy) (06878125BE78B42C,970916184804,jdun@scuc.edu.au) (06878125BE78B42C,970916185100,tborges@inetminas.estaminas.com.br) (B0C1B6DC7370F24B,970916090623,hhtp://www.yale.edu/opa.) (1432F28A749F7BE6,970916220548,nesticle 0.40 download) (1432F28A749F7BE6,970916221400,nes rom) (1432F28A749F7BE6,970916221804,double dragon 3 rom) (1432F28A749F7BE6,970916221859,emuland) (98F5BBD3754D292F,970916082614,powwow.com) (98F5BBD3754D292F,970916082616,powwow.com) (98F5BBD3754D292F,970916082713,powwow.com tribal ) (C5D01E05FF9CA265,970916155706,mary lou allgood) (C5D01E05FF9CA265,970916155729,mary lou allgood) (DB38E7AF26F3AD9A,970916114356,microsoft excel)不要なデータを削除するためにはFILTERを使う
条件を指定して不要なデータ行を削除するためにFILTERを利用します。下のサンプルではUDFで定義されたorg.apache.pig.tutorial.NonURLDetector(query)を利用してqueryが空またはURL形式で無い場合は変数に格納するという処理をしています。UDFの中では単純にTrue/Falseをreturnするだけです。もっと簡単な例だと空かどうかの判定だけであればquery != ''のように指定することもできます。文字列比較ではeqという演算子で一致を確認することができます。eqは==と等価です。しかし不一致のneは使えません。またFILTERは数値演算も可能です。BY score > 2.0のように指定するとできます。更に便利なことにFILTERには正規表現も使え、指定にはMATCHESを利用します。
clean1 = FILTER raw BY org.apache.pig.tutorial.NonURLDetector(query); clean2 = FILTER raw BY query != ''; clean2 = FILTER raw BY query eq ''; clean2 = FILTER raw BY query == ''; -- clean2 = FILTER raw BY query eq ''; -- 指定できない clean2 = FILTER raw BY query MATCHES '.*university.*'; filtered_uniq_frequency = FILTER uniq_frequency3 BY score > 2.0;カラムデータに対して繰り返し処理を加えたい場合はFOREACHを利用する
抽出された行のカラムに対して特定の処理を繰り返し加えたい場合はFOREACH 変数名 GENERATEを利用します。下ではURLや空をFILTERした行に対して、queryを小文字に変換し、timeを検索時間に変換し、ngramに分割したデータがタプル形式になっているので、それをフラット化するためにFLATTENを使っています。tutorialの例ではFOREACHを3行使っていて面倒なので、1行にまとめてしまうことも出来ます。
clean1 = FILTER raw BY org.apache.pig.tutorial.NonURLDetector(query); clean2 = FOREACH clean1 GENERATE user, time, org.apache.pig.tutorial.ToLower(query) AS query; houred = FOREACH clean2 GENERATE user, org.apache.pig.tutorial.ExtractHour(time) AS hour, query; ngramed1 = FOREACH houred GENERATE user, hour, FLATTEN(org.apache.pig.tutorial.NGramGenerator(query)) AS ngram; DUMP ngramed1; -- 上のFOREACHを1行でまとめる ngramed1 = FOREACH clean1 GENERATE user, org.apache.pig.tutorial.ExtractHour( time ) AS hour, FLATTEN( org.apache.pig.tutorial.NGramGenerator( org.apache.pig.tutorial.ToLower( query ) ) ) AS ngram;-- フラット化されたデータ (C5D01E05FF9CA265,15,allgood) (C5D01E05FF9CA265,15,lou allgood) (C5D01E05FF9CA265,15,lou) (C5D01E05FF9CA265,15,mary) (C5D01E05FF9CA265,15,mary lou) (C5D01E05FF9CA265,15,allgood) (C5D01E05FF9CA265,15,lou allgood) (C5D01E05FF9CA265,15,lou) (C5D01E05FF9CA265,15,mary) (C5D01E05FF9CA265,15,mary lou) (DB38E7AF26F3AD9A,11,excel) (DB38E7AF26F3AD9A,11,microsoft excel) (DB38E7AF26F3AD9A,11,microsoft) -- フラット化されていないデータ (98F5BBD3754D292F,08,{(com),(powwow com),(powwow)}) (98F5BBD3754D292F,08,{(com),(powwow com),(powwow)}) (98F5BBD3754D292F,08,{(com),(powwow com),(tribal),(powwow),(com tribal)}) (C5D01E05FF9CA265,15,{(allgood),(lou allgood),(lou),(mary),(mary lou)}) (C5D01E05FF9CA265,15,{(allgood),(lou allgood),(lou),(mary),(mary lou)}) (DB38E7AF26F3AD9A,11,{(excel),(microsoft excel),(microsoft)})重複された行を削除しUniqしたい場合はDISTINCTを使う
重複された行を削除したい場合はDISTINCTを利用します。RDBMSを使っている人なら馴染みある機能だと思います。
ngramed2 = DISTINCT ngramed1; DUMP ngramed2;
(FFA4F354D3948CFB,05,big cocks) (FFA4F354D3948CFB,06,big) (FFA4F354D3948CFB,06,cocks) (FFA4F354D3948CFB,06,big cocks) (FFCA848089F3BA8C,10,manson) (FFCA848089F3BA8C,10,marilyn) (FFCA848089F3BA8C,10,marilyn manson)データのグループ化をしたい場合はGROUPを使う
特定の条件でデータのグループ化をしたい場合はGROUPを利用します。下の例では検索時間,ngramの二つでuserのListをGROUPとして1行で出力しています。
hour_frequency1 = GROUP ngramed2 BY (ngram, hour); DUMP hour_frequency1;((university,11),{(752FE259E734662C,11,university),(1C29DA34960DE1A9,11,university)}) ((university,13),{(0E10DD8EB5EEB192,13,university),(C983FC6A580A67D4,13,university)}) ((university,14),{(0D49AC0B76523A18,14,university),(6946DDFE6F9050F5,14,university),(C983FC6A580A67D4,14,university)})データの個数をカウントする場合はCOUNTを使う
データの個数をカウントするにはCOUNTを利用します。下の例では上でGROUP化されたデータのタプル数をカウントする例になります。(ngram,hour)のカラムが$0、GROUP化された(user,hour,ngram)カラムが$1に相当し、COUNT($1)の式によって((university,14),{(0D49AC0B76523A18,14,university),(6946DDFE6F9050F5,14,university),(C983FC6A580A67D4,14,university)})が(university,14,3)として3つカウントされます。
hour_frequency2 = FOREACH hour_frequency1 GENERATE flatten($0), COUNT($1) as count; DUMP hour_frequency2;(universita,09,1) (university,01,1) (university,06,1) (university,09,1) (university,10,1) (university,11,2) (university,13,2) (university,14,3) (university,15,1) (university,19,1) (university,21,1) (univiristy,06,1)一つの項目だけでグループ化
ここもGROUPの使い方の説明です。事前にグループ化されたデータをngramだけで再度グループ化しています。よくやってしまう間違いとしてBY ngram;と指定しまうことです。hour_frequency2にはngramという項目がありません。hour_frequency1でgroupされたngramが存在しているだけなので、group::ngramと指定します。
uniq_frequency1 = GROUP hour_frequency2 BY group::ngram; -- uniq_frequency1 = GROUP hour_frequency2 BY group::ngram; -- 良くやる間違い DUMP uniq_frequency1;(universita,{(universita,09,1)}) (university,{(university,14,3),(university,01,1),(university,06,1),(university,09,1),(university,10,1),(university,11,2),(university,13,2),(university,15,1),(university,19,1),(university,21,1)}) (univiristy,{(univiristy,06,1)})指定したカラムでソートしたい場合はORDERを使う
特定のカラムでデータをソートしたい場合はORDERを利用します。DISTINCTと同様にRDBMSにもある機能ですね。下の例ではngramのscore化されたデータをFILTERにてscore > 2.0の行を抽出し、hour/scoreの項目でソートをした結果を格納しています。ORDER BYはASCで昇順、DESCで降順にソートすることができます。
uniq_frequency3 = FOREACH uniq_frequency2 GENERATE $1 as hour, $0 as ngram, $2 as score, $3 as count, $4 as mean; filtered_uniq_frequency = FILTER uniq_frequency3 BY score > 2.0; ordered_uniq_frequency = ORDER filtered_uniq_frequency BY hour, score; -- 昇順ソート ordered_uniq_frequency = ORDER filtered_uniq_frequency BY hour DESC; -- 降順ソート-- DESC (19,in,2.1572774865200244,3,1.4285714285714284) (19,car,2.23606797749979,3,1.3333333333333333) (17,chat,2.9104275004359965,3,1.2857142857142854) (15,adult,2.8284271247461903,2,1.1111111111111112) (14,music,2.1105794120443453,4,1.6666666666666667) (14,city,2.2360679774997902,2,1.1666666666666665) (14,university,2.412090756622109,3,1.4000000000000001) (13,the,3.1309398305840723,6,1.9375) (11,in,2.1572774865200244,3,1.4285714285714284) (11,pictures,2.04939015319192,3,1.4999999999999998) (10,free,2.2657896674010605,4,1.923076923076923) (10,to,2.6457513110645903,2,1.125) (10,pics,2.794002794004192,3,1.3076923076923075) (10,school,2.828427124746189,2,1.1111111111111114) (08,computer,2.4494897427831788,2,1.1428571428571426) (08,pictures,2.04939015319192,3,1.4999999999999998) (08,s,2.545584412271571,3,1.3636363636363635) (07,new,2.4494897427831788,2,1.1428571428571426)データの結合にはJOINを使う
二つの変数間のデータを結合するにはJOINを利用します。JOINには内部結合(INNER)と外部結合等(LEFT,RIGHT,FULL)の種類があり、何も指定しない場合は内部結合になります。
same = JOIN hour00 BY $0, hour12 BY $0; -- 内部結合 same = JOIN hour00 BY $0 LEFT, hour12 BY $0; -- 左外部結合 same = JOIN hour00 BY $0 RIGHT, hour12 BY $0; -- 右外部結合 same = JOIN hour00 BY $0 FULL, hour12 BY $0; -- 全外部結合-- JOIN RIGHT (,,,applied technologies,12,1) (,,,horoscope benmcnenly,12,1) (,,,providers california,12,1) (,,,snowboarding kirkwood,12,1) (,,,snowboarding kurkwood,12,1) (,,,instrument instruments,12,1) (,,,vietnam telecommunications,12,1)データを保存したい場合はSTOREを使う
Pigで実行したデータをファイルに保存したい場合はSTOREを利用します。STOREもLOADと同様にUSINGでデータのparserを指定することが出来ます。下の例ではPigStorageを指定しているのでtab区切りのデータ保存になります。INTOで指定するのは結果を保存するディレクトリです。ディレクトリの中にpart-r-00000というファイルができるので、それが出力結果になります。結果は一番上で実行したスクリプトの結果になります。
STORE ordered_uniq_frequency INTO 'script1-local-results' USING PigStorage();
Advanced
以下ではtutorialに載っていない更なる応用例を記載します。入力サンプルのデータを変更して以下のタブ区切りで定義されているstudentデータを使います。データを変えたのは以下のページと結果を比較しやすくするためです。すいません。Pig Latin Basics
John 18 4.0F Mary 19 3.8F Bill 20 3.9F Joe 18 3.8F変数のデータ型を調べる時はDESCRIBEを使う
DESCRIBEは変数のデータ型を出力します。FLATTEN等の処理を入れる時にデータ型を確認するために利用すると便利です。
raw1 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); DESCRIBE raw1;raw: {name: chararray,age: int,gpa: float}2つ以上の変数をグループ化する時はCOGROUPを使う
2つ以上の変数をグループ化したい時はCOGROUPを利用します。データや使い方の形式はGROUPと同じです。下では3つの変数をCOGROUPしています。
raw1 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); raw2 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); raw3 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); filter_raw2 = FILTER raw2 BY age == 18; co_data = COGROUP raw1 BY age, filter_raw2 BY age, raw3 BY age; DUMP co_data;(18,{(John,18,4.0),(Joe,18,3.8)},{(John,18,4.0),(Joe,18,3.8)},{(John,18,4.0),(Joe,18,3.8)}) (19,{(Mary,19,3.8)},{},{(Mary,19,3.8)}) (20,{(Bill,20,3.9)},{},{(Bill,20,3.9)})データの組み合わせを全て取得する時はCROSSを使う
2つ以上の変数の組み合わせを全て取得したい時はCROSSを利用します。全ての組み合わせを作るので処理が凄く重くなるようなので注意して使うといいと思います。
raw1 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); raw2 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); filter_raw2 = FILTER raw2 BY age == 18; cross_data = CROSS raw1, filter_raw2; DUMP cross_data;(John,18,4.0,Joe,18,3.8) (John,18,4.0,John,18,4.0) (Mary,19,3.8,Joe,18,3.8) (Mary,19,3.8,John,18,4.0) (Joe,18,3.8,Joe,18,3.8) (Joe,18,3.8,John,18,4.0) (Bill,20,3.9,Joe,18,3.8) (Bill,20,3.9,John,18,4.0)2つのデータの統合はUNIONを使う
2つ以上の変数を統合したい場合はUNIONを利用します。CROSSと違いUNIOは単純なデータの追加になります。
raw1 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); raw2 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); filter_raw2 = FILTER raw2 BY age == 18; union_data = UNION raw1, filter_raw2; DUMP union_data;(John,18,4.0) (Mary,19,3.8) (Bill,20,3.9) (Joe,18,3.8) (John,18,4.0) (Joe,18,3.8)結果の個数を絞りたい時はLIMITを使う
ORDER BYとの組み合わせで取得したい結果を絞りたい時はLIMITを利用します。単純に変数に対して個数を設定するだけです。
raw1 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); raw2 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); filter_raw2 = FILTER raw2 BY age == 18; union_data = UNION raw1, filter_raw2; order_data = ORDER union_data by age DESC; limit_data = LIMIT order_data 2; DUMP limit_data;(Bill,20,3.9) (Mary,19,3.8)ランダムサンプリングを取得したい時はSAMPLEを使う
取得したいランダムサンプルの割合をSAMPLEで指定します。指定方法はSAMPLE 変数名 割合実数です。
raw1 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); raw2 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); filter_raw2 = FILTER raw2 BY age == 18; union_data = UNION raw1, filter_raw2; sample_data = SAMPLE union_data 0.1; DUMP sample_data;(John,18,4.0)データを条件で分割したい場合はSPLITを使う
データを特定の条件で複数の変数に分割したい場合はSPLITを利用します。SPLITは複数の変数における条件を1行で表現できますが、動作内容としてはFILTERと同様でFILTERでも表記することが出来ます。
raw1 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); raw2 = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float); filter_raw2 = FILTER raw2 BY age == 18; union_data = UNION raw1, filter_raw2; SPLIT union_data INTO x_data IF age > 19, y_data IF age == 19, z_data IF age < 19; DUMP y_data;(Mary,19,3.8)NativeのMapReduceを実行するにはMAPREDUCEを使う
こちら実行を試していませんが、NativeのMapReduceを実行したい時にはMAPREDUCEを利用します。以下のスクリプトにinputDir,outputDirを指定して実行します。
A = LOAD 'WordcountInput.txt'; B = MAPREDUCE 'wordcount.jar' STORE A INTO 'inputDir' LOAD 'outputDir' AS (word:chararray, count: int) `org.myorg.WordCount inputDir outputDir`;