2

我正在尝试删除任何字段中至少包含一个 null 的记录。例如,如果数据有 3 个字段,则:

filtered = FILTER data by ($0 is not null) AND ($1 is not null) AND ($2 is not null)

有没有更简洁的方法可以做到这一点,而不必写出 3 个布尔表达式?

4

2 回答 2

8

如果所有字段都是数字类型,您可以简单地执行类似的操作

filtered = FILTER data BY $0*$1*$2 is not null;

在 Pig 中,如果算术表达式中的任何项为空,则结果为空。

您还可以编写一个 UDF 来获取任意数量的参数,并在任何参数为 null 时返回 null(或 0,或 false,只要您认为最方便)。

filtered = FILTER data BY NUMBER_OF_NULLS($0, $1, $2) == 0;

其中 NUMBER_OF_NULLS 在别处定义,例如

public class NUMBER_OF_NULLS extends EvalFunc {
    public Integer exec(Tuple input) {
        if (input == null) { return 0; }

        int c = 0;
        for (int i = 0; i < input.size(); i++) {
            if (input.get(i) == null) c++;
        }
        return c;
    }
}

注意:我没有测试过上面的 UDF,我并不声称它遵循任何编写清晰、健壮的 UDF 的最佳实践。例如,您应该添加异常处理代码。

于 2012-10-18T20:47:55.033 回答
0

我在想有一种更好的方法可以在不使用 UDF 的情况下执行此操作,即在 Pig 中使用 SPLIT。

emp = load '/Batch1/pig/emp' using PigStorage(',') as (id:chararray, name:chararray, salary:int, dept:chararray);

SPLIT emp INTO emptyDept IF depart == '', nonemptyDept IF depart != '';

DUMP nonemptyDept;

生成的关系 nonemptyDept将显示 emp 关系的所有非空 Department 值。

于 2019-11-02T01:51:48.573 回答