1

我执行以下操作:

a = load '/hive/warehouse/' USING PigStorage('^') as (a1,b1,c1);

b = group a by (a1) ;

c = foreach b generate group, a.$2;

dump c;

输出显示所有组:

abc  {(1),(44),(66)}
cde  {(1),(44),(66)}

如何删除“{”和“(”字符,以便最终的 HDFS 文件可以作为逗号分隔文件读取?

4

3 回答 3

3

您不能直接在 Pig 中执行此操作。需要特殊语法,因为您正在存储一个包,并且为了让 Pig 以后能够读取这个包,它需要用大括号(用于包)和括号(用于包中包含的元组)存储。

你有几个选择。您可以将文件读回 Pig,但不是将其读取为 ,而是将其bag读取为chararray. 然后您可以执行正则表达式替换以摆脱标点符号(未经测试):

a = LOAD 'output' AS (group:chararray, list:chararray);
b = FOREACH A GENERATE group, REPLACE(list, '[{()}]', '');

另一种选择是编写一个 UDF,它将一个包变成一个元组。请注意,这不是一个定义明确的操作:袋子没有特定的顺序,因此从一个运行到下一个运行,您的元组不能保证处于相同的顺序。但就您的目的而言,这听起来可能无关紧要。UDF 可能看起来像(非常粗略的草稿,未经测试):

public class BAG_TO_TUPLE extends EvalFunc(Tuple) {
    public Tuple exec(Tuple input) {
        DataBag bag = input.get(0);
        Iterator<Tuple> iterator = bag.iterator();

        Tuple out = new DefaultTuple();
        while(iterator.hasNext()) {
            out.append(iterator.next().get(0));   
        }

        return out;
    }
}

上面的 UDF 很糟糕——它假设你在包的每个元组中都有一个元素(你关心的),并且不检查输入是否有效等。但它应该让你达到你想要的。

但是,如果 Pig 不是下游处理的一部分,最好的解决方案是找到一种方法来处理 Pig 之外的额外标点符号。

于 2013-01-28T22:35:41.357 回答
1

此功能现在在 Pig 中作为内置函数提供(我使用的是 0.11)。

http://pig.apache.org/docs/r0.11.0/api/org/apache/pig/builtin/BagToString.html

c = foreach b generate group, a.$2 as stuff;
d = foreach c generate group, BagToString(stuff, ',');

对于我的用例,我不需要逗号分隔的文件,但我假设您可以使用 store func 来获取最终的逗号(在 group 和 now-comma-delimited-list of bag 事物之间)。

于 2014-05-12T17:16:37.057 回答
0

试试 FLATTEN 运算符;

c = foreach b 生成组,FLATTEN(a.$2);

于 2013-01-28T20:12:22.977 回答