Apache Pig:组操作后去除命名空间前缀 (::)

Posted

技术标签:

【中文标题】Apache Pig:组操作后去除命名空间前缀 (::)【英文标题】:Apache Pig: strip namespace prefix (::) after group operation 【发布时间】:2012-06-11 22:42:30 【问题描述】:

我的数据处理中的一个常见模式是按一组列分组,应用过滤器,然后再次展平。例如:

my_data_grouped = group my_data by some_column;
my_data_grouped = filter my_data_grouped by <some expression>;
my_data = foreach my_data_grouped flatten(my_data);

这里的问题是,如果my_data 在此操作之后以 (c1, c2, c3) 之类的模式开头,它将具有 (mydata::c1, mydata::c2, mydata::c3) 之类的模式。如果列是唯一的,有没有办法轻松去除“mydata::”前缀?

我知道我可以这样做:

my_data = foreach my_data generate c1 as c1, c2 as c2, c3 as c3;

但是,对于具有大量列的数据集,这会变得笨拙且难以维护,而对于具有可变列的数据集则不可能。

【问题讨论】:

【参考方案1】:

如果架构中的所有字段都具有相同的前缀集(例如 group1::id、group1::amount 等),您可以在引用特定字段时忽略前缀(只需将它们引用为 id、amount 等)

或者,如果您仍然希望去除单级前缀的架构,您可以使用这样的 UDF:

public class RemoveGroupFromTupleSchema extends EvalFunc<Tuple> 

@Override
public Tuple exec(Tuple input) throws IOException 
    Tuple result = input;
    return result;



@Override
public Schema outputSchema(Schema input) throws FrontendException 
    if(input.size() != 1) 
        throw new RuntimeException("Expected input (tuple) but input does not have 1 field");
    

    List<Schema.FieldSchema> inputSchema = input.getFields();
    List<Schema.FieldSchema> outputSchema = new ArrayList<Schema.FieldSchema>(inputSchema);
    for(int i = 0; i < inputSchema.size(); i++) 
        Schema.FieldSchema thisInputFieldSchema = inputSchema.get(i);
        String inputFieldName = thisInputFieldSchema.alias;
        Byte dataType = thisInputFieldSchema.type;

        String outputFieldName;
        int findLoc = inputFieldName.indexOf("::");
        if(findLoc == -1) 
            outputFieldName = inputFieldName;
        
        else 
            outputFieldName = inputFieldName.substring(findLoc+2);
        
        Schema.FieldSchema thisOutputFieldSchema = new Schema.FieldSchema(outputFieldName, dataType);
        outputSchema.set(i, thisOutputFieldSchema);
    

    return new Schema(outputSchema);


【讨论】:

如何使用这个UDF?提前致谢。【参考方案2】:

您可以将“AS”语句与“foreach”放在同一行。

my_data_grouped = group my_data by some_column;
my_data_grouped = filter my_data_grouped by <some expression>;
my_data = FOREACH my_data_grouped FLATTEN(my_data) AS (c1, c2, c3);

但是,这与在 2 行上执行此操作相同,并且不会缓解您对“具有可变列的数据集”的问题。

【讨论】:

以上是关于Apache Pig:组操作后去除命名空间前缀 (::)的主要内容,如果未能解决你的问题,请参考以下文章

怎么在文件夹里统一修改文件前缀

laravel入门教程

提交作业后如何调试Pig被卡住

如何避免 GDB 中符号的命名空间前缀?

XSL:删除命名空间前缀

Pig UDF - 将动态模式作为一组字段(不是元组)返回