我将参考前面的问题。基本上我有这两个数据集。使用场地名称,我想输出每个场地在推特消息中出现的次数。我得到的答案对小数据集来说很好,但想象一下,我有10000个场地和20000条使用CROSS
的推特消息,这将使我与200米记录建立关系,这相当多。
上一个问题中介绍了简单的数据集,我目前使用的PIG脚本如答案中所示。我正在寻找如何在没有CROSS
产品的情况下进行计数的想法。谢谢
REGISTER piggybank.jar
venues = LOAD 'venues_mid' USING org.apache.hcatalog.pig.HCatLoader();
tweets = LOAD 'tweets_mid' USING org.apache.hcatalog.pig.HCatLoader();
tweetsReduced = foreach tweets generate text;
venuesReduced = foreach venues generate name;
/* Create the Cartesian product of venues and tweets */
crossed = CROSS venuesReduced, tweetsReduced;
/* For each record, create a regex like '.*name.*' */
regexes = FOREACH crossed GENERATE *, CONCAT('.*', CONCAT(venuesReduced::name, '.*')) AS regex;
/* Keep tweet-venue pairs where the tweet contains the venue name */
venueMentions = FILTER regexes BY text MATCHES regex;
venueCounts = FOREACH (GROUP venueMentions BY venuesReduced::name) GENERATE group, COUNT($1) as counter;
venueCountsOrdered = order venueCounts by counter;
STORE venueCountsOrdered INTO 'Pig_output/venueCountsOrdered_mid.csv'
USING org.apache.pig.piggybank.storage.CSVExcelStorage(',', 'NO_MULTILINE', 'WINDOWS');
tweets.csv
created_at,text,location
Sat Nov 03 13:31:07 +0000 2012, Sugar rush dfsudfhsu, Glasgow
Sat Nov 03 13:31:07 +0000 2012, Sugar rush ;dfsosjfd HAHAHHAHA, London
Sat Apr 25 04:08:47 +0000 2009, at Sugar rush dfjiushfudshf, Glasgow
Thu Feb 07 21:32:21 +0000 2013, Shell gggg, Glasgow
Tue Oct 30 17:34:41 +0000 2012, Shell dsiodshfdsf, Edinburgh
Sun Mar 03 14:37:14 +0000 2013, Shell wowowoo, Glasgow
Mon Jun 18 07:57:23 +0000 2012, Shell dsfdsfds, Glasgow
Tue Jun 25 16:52:33 +0000 2013, Shell dsfdsfdsfdsf, Glasgow
场馆.csv
city,name
Glasgow, Sugar rush
Glasgow, ABC
Glasgow, University of Glasgow
Edinburgh, Shell
London, Big Ben
你可能想做的不是CROSS,而是"按地点、按城市加入推特"。
另一个尝试:
我能想到的最好的方法是"编写UDF,它加载所有10K场地,并编译所有场地名称的一个正则表达式模式(应该适合主内存=10K*500字节)UDF将获取匹配的推特消息和场地的输出名称。对于每条推特消息,您将调用此UDF。因为在每个映射器中加载10万个场地需要时间,所以您可能需要向每个映射器发送更多的推特消息,否则您将花费大部分时间加载场地。我认为你通过这样做真正获得的不是2亿的中间产量。
UDF可能会在前端加载数据并直接输出场地时表现更好。但是由于您请求了一个没有UDF的解决方案。由于您的场地表非常小,因此您可以执行片段复制联接。
tweets = LOAD 'tweets';
venues = LOAD 'venues';
joined = JOIN tweets by location, venues by city using 'replicated';
现在,您可以将joined
关系与感兴趣的字段进行投影。建议的UDF基本上是对复制联接算法的优化。事实上,现在我想一想,在UDF中,它可能不会有更多(或更少)的性能。我的猜测是,执行计划将保持完全相同。你可以尝试两种方法,看看哪一种更好。