UDF的问题

时间:2015-06-05 08:50:58

标签: junit apache-pig udf

我有一个UDF接受一个包作为输入并将其转换为地图。地图的每个键都包含在包中的不同元素以及与其计数相对应的值

但它没有通过junit测试

2 个答案:

答案 0 :(得分:0)

除了使用一包两个元组之外,你似乎还在创建一个包含两个字段的元组的包。

此代码:

DataBag dataBag = bagFactory.newDefaultBag();
Tuple nestedTuple = tupleFactory.newTuple(2);
nestedTuple.set(0, "12345");
nestedTuple.set(1, "12345");
dataBag.add(nestedTuple);

应转换为:

DataBag dataBag = bagFactory.newDefaultBag();
Tuple tupleA = tupleFactory.newTuple(1);
tupleA.set(0, "12345");
dataBag.add(tupleA);

Tuple tupleB = tupleFactory.newTuple(1);
tupleB.set(0, "12345");
dataBag.add(tupleB);

或者你可以迭代你所有的元组字段。

答案 1 :(得分:0)

1的输出是正确的:在您的UDF中,您计算​​的是第一个字段具有相同值的元组数,但在测试中,您只添加一个具有两个值的元组。

如果你想要的是计算与"键"相同值的元组数。 (其中key是元组中的第一个值),那么你所做的是正确的,但你必须改变你的测试:

public void testExecWithSimpleMap() throws Exception {
    Tuple inputTuple = tupleFactory.newTuple(1);
    DataBag dataBag = bagFactory.newDefaultBag();
    Tuple nestedTuple = tupleFactory.newTuple(2);
    nestedTuple.set(0, "12345");
    nestedTuple.set(1, "another value");
    dataBag.add(nestedTuple);

    // Add a second tuple
    nestedTuple.set(0, "12345");
    nestedTuple.set(1, "and another value");
    dataBag.add(nestedTuple);
    inputTuple.set(0,dataBag);
    Map output = testClass.exec(inputTuple);
    assertEquals(output.size(), 1);
    System.out.println(output.get("12345"));
    assertEquals(output.get("12345"),2);
}

然而,如果你想要的是计算整个Bag中重复值的次数,无论它是在不同的元组上还是在同一个元组中,(在你的问题中不是很清楚),那么你需要改变你的UDF:

public class BagToMap extends EvalFunc<Map> {
    public Map exec(Tuple input) throws IOException {
        if(input == null) {
            return null;
        }
        DataBag values = (DataBag)input.get(0);
        Map<String, Integer> m = new HashMap<String, Integer>();
        for (Iterator<Tuple> it = values.iterator(); it.hasNext();) {
            Tuple t = it.next();

            // Iterate through the Tuple as well
            for (Iterator<Object> it2 = t.iterator(); it2.hasNext();) {
                Object o = it2.next();
                String key = o.toString();

                if(m.containsKey(key)) {
                    m.put(key, m.get(key)+1);
                } else {
                    m.put(key, 1);
                }
            }
        }
        return m;
    }
}

在这种情况下,您的测试应该通过。