用猪换一个元组

时间:2016-05-02 01:48:24

标签: tuples apache-pig udf

我需要使用Pig UDF替换元组的字符。例如,如果我在文件中有一行" hello world,Hello WORLD,hello \ WORLD"需要转换为" hello_world,hello_world,hello_world"。为了实现这一点,我尝试了以下UDF:

package myUDF;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;
public class ReplaceValues extends EvalFunc<Tuple>
{
    public Tuple exec(Tuple input) throws IOException {
        if (input == null || input.size() == 0)
            return null;
     try{
           String str = (String)input.get(0);
           str=str.replace(" ", "_");
           str=str.replace("/","");
           str=str.replace("\\","");
           TupleFactory tf = TupleFactory.getInstance();
           Tuple t = tf.newTuple();
           t.append(str);
           return t;
    }catch(Exception e){
        throw new IOException("Caught exception processing input row ", e);
    }
  }
}

但是当我通过猪脚本调用这个UDF我遇到问题时,请帮我解决这个问题:

A = load '/user/cloudera/Stage/ActualDataSet.csv' using PigStorage(',') AS (Rank:chararray,NCTNumber:chararray,Title:chararray,Recruitment:chararray);
B = FILTER A by Rank == 'Rank';
C = FOREACH B GENERATE PigUDF.ReplaceValues(B);

错误:Pig脚本无法解析:  无效的标量投影:B:需要从关系中投射一个列,以便将其用作标量

2 个答案:

答案 0 :(得分:0)

你必须传递你想要修改的字段而不是关系B.假设你想要匹配的字段是Title,那么你可以像下面那样调用UDF

C = FOREACH B GENERATE B.Rank,B.NCTNumber,PigUDF.ReplaceValues(B.Title),B.Recruitment;

请注意,如果您尝试在整个记录中替换它,那么您的load语句不正确。您必须将整个记录加载为line:chararray,然后将line传递给您的UDF 。

此外,您可以使用REGEX来匹配并替换您选择的字符串,而不是UDF。

答案 1 :(得分:0)

在你的Pig脚本中,你在UDF中传递整个Bag“ B ”,而它接受元组作为参数。

相反传递像B.Title这样的字段,如下所示。

C = FOREACH B GENERATE PigUDF.ReplaceValues(B.Title);

您也可以在与其他字段相同的行中调用此UDF:

C = FOREACH B GENERATE PigUDF.ReplaceValues(B.Title), PigUDF.ReplaceValues(B.Rank);