我需要使用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:需要从关系中投射一个列,以便将其用作标量
答案 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);