【问题标题】:Pig UDF that produces output with the same schema as its input产生与输入具有相同模式的输出的 Pig UDF
【发布时间】:2025-11-21 11:15:01
【问题描述】:

我正在尝试创建一个接受元组并返回元组的 UDF。

A = LOAD 'file.txt' USING PigStorage(',') AS (f1:chararray);
DESCRIBE A
A: {f1: chararray}
B = FOREACH A GENERATE MyUDF(*);
DESCRIBE B
B: {(f1: chararray)}

但是,我希望 B 的形式为 {f1: chararray},即我不想要包含包含 chararray 的元组的包,而是包含包含 chararray 的元组的包。

我可以使用FLATTEN,但架构如下所示: B: {null::f1: chararray} 但我需要它是{f1: chararray}

这是我的 UDF 的代码:

public class MyTest extends EvalFunc<Tuple> {

    public MyTest() {
    }

    @Override
    public Tuple exec(final Tuple input) throws IOException {
        //apply some logic (not relevant)
        return input;
    }

    @Override
    public Schema outputSchema(final Schema input) {
        try {
            final Schema outputTupleSchema = input.clone();
            return outputTupleSchema;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

有人知道如何实现吗?任何帮助将不胜感激。

【问题讨论】:

    标签: apache-pig


    【解决方案1】:

    可能有其他方法可以解决这个问题,但最简单的是您已经在使用的方法:FLATTEN。为什么不直接分配您真正想要的名称?无论如何你都必须FLATTEN,因为你的UDF返回一个元组,而且没有办法解决这个问题。

    B = FOREACH A GENERATE FLATTEN(MyUDF(*)) AS f1;
    

    如果您想对很多字段执行此操作,这可能会变得很麻烦,但仍有一些方法可以最大限度地减少输入。 (例如,等到您执行了这个 UDF 后才提供您的架构,而不是在 LOAD 语句中这样做)。

    【讨论】:

    • 问题是我需要 udf 中的模式,所以我必须在加载和 foreach 中都指定它。还是谢谢!
    • 考虑我有 500 个库,我不想要 schema::f1 而只是 f1,那么在这种情况下应该怎么做? return new Schema(new Schema.FieldSchema("schema", tupleSchema));。这是我来自output schema()的回复声明。