我有这样的数据:
2013-11 localhost kern
2013-11 localhost kern
2013-11 192.168.0.59 daemon
2013-12 localhost kern
2013-12 localhost daemon
2013-12 localhost mail
你明白了。我正在尝试按日期对上面进行分组(作为行键),并且有一列对应于每个kern
,daemon
等的计数。简而言之,我想要的输出应该是下面:
-- date, count(kern), count(daemon), count(mail)
(2013-11, 2, 1, 0)
(2013-12, 1, 1, 1)
目前,我的方法是这样的。
valid_records = FILTER formatted_records BY date is not null;
date_group = GROUP valid_records BY date;
facilities = FOREACH date_group {
-- DUMB way to filter for now :(
kern = FILTER valid_records BY facility == 'kern';
user = FILTER valid_records BY facility == 'user';
daemon = FILTER valid_records BY facility == 'daemon';
-- this need to be in order so it get mapped correctly to HBase
GENERATE group, COUNT(kern), COUNT(user), COUNT(daemon);
}
两个问题:
我上面有3个过滤器,但在生产中,应该有超过10个过滤器。如果我使用上面的很多FILTER
,是否会有任何性能影响?
还有其他更好的方法吗?
答案 0 :(得分:1)
我认为您的问题是您正在寻找具有浮动模式的输出。但似乎您所要做的就是按复合键分组: 用这个脚本:
formatted_records = LOAD 'input' AS (date: chararray, host: chararray, facility: chararray);
valid_records = FILTER formatted_records BY date is not null;
counts = FOREACH (GROUP valid_records BY (date, facility)) GENERATE
group.date AS date,
group.facility AS facility,
COUNT(valid_records) AS the_count;
DUMP counts;
你会得到:
(2013-11,kern,2)
(2013-11,daemon,1)
(2013-12,kern,1)
(2013-12,mail,1)
(2013-12,daemon,1)
给出了相同的信息。
如果你想像你那样花哨地格式化输出,那么最好分别使用通用语言(如Java或Python)来完成这些任务(假设Pig的输出足够小以适应内存) 。猪并不擅长这个。
答案 1 :(得分:0)
只要你有一个群组操作,你就会有一个减少阶段,这意味着你很可能有编写临时映射器输出,二次排序等的开销。还有其他猪操作员会触发减少阶段,但我认为FILTER
不是其中之一:映射器任务可以过滤输入并创建多个输出,然后将其排序并发送到单个减少阶段。
换句话说,在猪身上看起来很混乱的东西实际上可以非常高效,看起来简洁的东西可以产生比你想象的更多的地图减少开销。
如果从命令行运行pig作业,您将看到正在使用的运算符的摘要以及逻辑计划产生的M / R作业列表。