使用关系数据库映射Reduce

时间:2014-03-19 03:23:59

标签: mysql database hadoop mapreduce yarn

我有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中的每个人运行此查询吗?

1 个答案:

答案 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代码,请告诉我。

谢谢!!