我有2个关系表
表A(人1,读书的标题)
表B(书名,作者姓名)
我正在创建一个map-reduce作业,按作者统计书籍,由表1中的每个人阅读。
这意味着如果同一作者有2本书并且该人同时阅读,那么map-reduce将会产生:
(Person1,作者1,2);
我的地图功能(在元级别)是:
map {
emit(TableB.BookTitle, 1)
}
我的reduce函数是:
reduce function (title,values)
{
while(values.hasNext())
{
if(title == tableA.bookRead)
sum+=values
}
output.collect(tableA.person1, tableB.author, sum)
}
我知道读书的人之间有一些漏洞,但我不确定如何接近它?我还必须为表B中的每个人运行此查询吗?
答案 0 :(得分:1)
我们可以将给定的问题分解为两个任务:
1)在第一部分中,我们应该用两个mapper创建一个map reduce作业。对于第一个映射器-A表A是输入,第二个Mapper-B表B是输入。并且只有一个减速器。 Mapper A发出" BooK Title"作为密钥和"人名#表-A"。 映射器B发出"书名"作为密钥和"作者姓名#表-B"
因为在Map-Reduce中,一个键的记录转到同一个reducer,在这个作业中我们只有一个reducer,所以记录会到达那里 {书名,
然后你需要实现逻辑来提取人名和作者姓名。在reducer端,Reducer将其输出作为: 书名%作者姓名%PersonName
例如。
while(values.hasNext())
{
String line = values.next().toString();
String[] det_array = line.split("#");
if(det_array[0].equals("person_book"))
{
person_name = det_array[1];
emit_value = emit_value + person_name + ",";
}
else if(det_array[0].equals("auth_book") && !author_seen)
{
author_name = det_array[1];
emit_value = emit_value + "%" + author_name + "%" + ",";
author_seen = true;
}
}
output.collect(new Text(key),new Text(emit_value));
然后您的最终输出文件将如下所示: 书名%Author_Name%人名
2)在第二个地图减少工作:代码只有一个Mapper和Reducer。您的工作输入格式为: 书名%Author_Name%Person Name1,PersonName2等..
对于您的Mapper输出键是Author_Name + Person,Value是1.
在此阶段,您在Reducer中拥有Author_Name和Person的组合,您只需要计算1并将其作为人名,作者姓名和总计数发出。
如果您不清楚这一点,或者您希望查看实际的Java代码,请告诉我。
谢谢!!