我是Pig的新手,仍然在探索做简单事情的有效方法。例如,我有一包活动
{"events":[{"event": ev1}, {"event": ev2}, {"event":ev3}, ....]}我想把它压缩成一个元组,比如
{"events":[ev1, ev2, ev3, ....]}在Pig中有实现这一点的方法吗?我让veen在这件事上挣扎了一段时间,但没有太多成功:
提前感谢
发布于 2015-06-02 23:51:23
看一下你的输入,你的模式似乎是这样的:
A: {name:chararray, vals:{(inner_name:chararray, inner_value:chararray)}}正如我在对你的问题的评论中提到的,实际上将它转换成一个只有inner_value的数组将是非常困难的,因为你不知道你可能有多少个字段。当你不知道字段的数量时,你应该总是尝试在Pig中使用一个包。
幸运的是,如果你真的可以使用一个包来做这件事,那么它是微不足道的:
-- Project out only inner_value from the bag vals
B = FOREACH A GENERATE name, vals.inner_value ;发布于 2015-06-03 00:21:32
感谢大家提供的信息丰富的评论。他们帮了我。
然而,我发现我遗漏了Schema的一个重要特性,即每个字段都有一个键和一个值(映射)。因此,现在我通过编写一个UDF将包转换为逗号分隔的值字符串来实现我想要的:
package BagCondenser;
import java.io.IOException;
import java.util.Iterator;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.Tuple;
public class BagToStringOfCommaSeparatedSegments
extends EvalFunc<String> {
@Override
public String exec(Tuple input) throws IOException {
// Condensed bag to be returned
String listOfSegmentIds = new String("");
// Cast the input to a bag
Object inputObject = input.get(0);
// Throw error if not bag-able input
if (!(inputObject instanceof DataBag))
throw new IOException("Expected input to be a bag, but got: "
+ inputObject.getClass());
// The input bag
DataBag bag = (DataBag) inputObject;
Iterator it = bag.iterator();
// Collect second fields of each tuple and add to the output bag
while(it.hasNext()) {
// If the return string already had values, append a ','
if ( ! listOfSegmentIds.equals("") )
listOfSegmentIds += ",";
Tuple tuple = (Tuple) it.next();
listOfSegmentIds += tuple.get(0).toString();
}
return listOfSegmentIds;
}
}https://stackoverflow.com/questions/30507895
复制相似问题