1

単語を数える代わりに、文字を数える必要があります。しかし、Apache Pig バージョン 0.8.1-cdh3u1 を使用してこれを実装する際に問題があります。

次の入力があるとします。

989;850;abcccc
29;395;aabbcc

出力は次のようになります。

989;850;a;1
989;850;b;1
989;850;c;4
29;395;a;2
29;395;b;2
29;395;c;2

これが私が試したものです:

A = LOAD 'input' using PigStorage(';') as (x:int, y:int, content:chararray);
B = foreach A generate x, y, FLATTEN(STRSPLIT(content, '(?<=.)(?=.)', 6)) as letters;
C = foreach B generate x, y, FLATTEN(TOBAG(*)) as letters;
D = foreach C generate x, y, letters.letters as letter;
E = GROUP D BY (x,y,letter);
F = foreach E generate group.x as x, group.y as y, group.letter as letter, COUNT(D.letter) as count;

A、B、および C はダンプできますが、「ダンプ D」は「エラー 2997: バックアップされたエラーから例外を再作成できません: java.lang.ClassCastException: java.lang.Integer を org.apache.pig.data にキャストできません」という結果になります。 .タプル"

dump C が表示されます (3 番目の値が奇妙なタプルであるにもかかわらず):

(989,850,a)
(989,850,b)
(989,850,c)
(989,850,c)
(989,850,c)
(989,850,c)
(29,395,a)
(29,395,a)
(29,395,b)
(29,395,b)
(29,395,c)
(29,395,c)

スキーマは次のとおりです。

grunt> describe A; describe B; describe C; describe D; describe E; describe F;
A: {x: int,y: int,content: chararray}
B: {x: int,y: int,letters: bytearray}
C: {x: int,y: int,letters: (x: int,y: int,letters: bytearray)}
D: {x: int,y: int,letter: bytearray}
E: {group: (x: int,y: int,letter: bytearray),D: {x: int,y: int,letter: bytearray}}
F: {x: int,y: int,letter: bytearray,count: long}

この豚のバージョンは TOBAG($2..$8) をサポートしていないようです。したがって、TOBAG(*) には x と y も含まれていますが、後で構文的に整理できます... UDF を書くのは避けたいですそれ以外の場合は、Java API を直接使用するだけです。

しかし、キャストエラーは本当にわかりません。誰か説明してくれませんか。

4

3 に答える 3

1

代わりに書くことを提案しcustom UDFます。迅速な生の実装は次のようになります。

package com.example;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.pig.EvalFunc;
import org.apache.pig.data.BagFactory;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.DataType;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;
import org.apache.pig.impl.logicalLayer.schema.Schema;

public class CharacterCount extends EvalFunc<DataBag> {

    private static final BagFactory bagFactory = BagFactory.getInstance();
    private static final TupleFactory tupleFactory = TupleFactory.getInstance();

    @Override
    public DataBag exec(Tuple input) throws IOException {
        try {

            Map<Character, Integer> charMap = new HashMap<Character, Integer>();

            DataBag result = bagFactory.newDefaultBag();
            int x = (Integer) input.get(0);
            int y = (Integer) input.get(1);
            String content = (String) input.get(2);

            for (int i = 0; i < content.length(); i++){
                char c = content.charAt(i);        
                Integer count = charMap.get(c);
                count = (count == null) ? 1 : count + 1;
                charMap.put(c, count);
            }

            for (Map.Entry<Character, Integer> entry : charMap.entrySet()) {
                Tuple res = tupleFactory.newTuple(4);
                res.set(0, x);
                res.set(1, y);
                res.set(2, String.valueOf(entry.getKey()));
                res.set(3, entry.getValue());
                result.add(res);
            }

            return result;

        } catch (Exception e) {
            throw new RuntimeException("CharacterCount error", e);
        }
    }

}

それを瓶に詰めて実行します:

register '/home/user/test/myjar.jar';
A = LOAD '/user/hadoop/store/sample/charcount.txt' using PigStorage(';') 
      as (x:int, y:int, content:chararray);

B = foreach A generate flatten(com.example.CharacterCount(x,y,content)) 
      as (x:int, y:int, letter:chararray, count:int);

dump B;
(989,850,b,1)
(989,850,c,4)
(989,850,a,1)
(29,395,b,2)
(29,395,c,2)
(29,395,a,2)
于 2012-11-06T12:05:37.093 に答える
0

私は 0.8 バージョンを持っていませんが、これを試していただけますか:

A = LOAD 'input' using PigStorage(';') as (x:int, y:int, content:chararray);
B = foreach A generate x, y, FLATTEN(STRSPLIT(content, '(?<=.)(?=.)', 6));
C = foreach B generate $0 as x, $1 as y, FLATTEN(TOBAG(*)) as letter;
E = GROUP C BY (x,y,letter);
F = foreach E generate group.x as x, group.y as y, group.letter as letter, COUNT(C.letter) as count;
于 2012-11-06T12:52:04.563 に答える