标签:mapreduce
SQL自连接
SQL自身连接,可以解决很多问题。下面举的一个例子,就是使用了SQL自身连接,它解决了列与列之间的逻辑关系问题,准确的讲是列与列之间的层次关系。
对于下面的表cp(存储的孩子和父母的关系),用一个SQL,找出所有的 grandchild 和 grandparent,就是找出所有的 孙子 -> 祖父母
+-------+--------+ | child | parent | +-------+--------+ | tom | jack | | hello | jack | | tom | tong | | jack | gao | | tom | jack | | hello | jack | | tong | haha | +-------+--------+
select t1.child,t2.parent from cp t1,cp t2 where t1.parent = t2.child;
结果如下:
+-------+--------+ | child | parent | +-------+--------+ | tom | gao | | hello | gao | | tom | haha | +-------+--------+
上面的SQL其实是做了一个笛卡尔积,怎么用MR算法来实现呢?
使用连接列作为key来实现相等匹配。需要让map的输出能包含左右两张表(t1,t2)的信息。
对于如下的输入文件:
Tom Lucy Tom Jack Jone Lucy Jone Jack Lucy Mary Lucy Ben Jack Alice Jack Jesse Terry Tom
Tom parent_Lucy Lucy child_Tom Tom parent_Jack Jack child_Tom .....
map函数如下:
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
String strs[] = value.toString().split(" ");
if (strs.length == 2) {
context.write(new Text(strs[0]), new Text("parent_" + strs[1]));
context.write(new Text(strs[1]), new Text("child_" + strs[0]));
}
}reduce函数:
public void reduce(Text text, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
List<Text> grandchilds = new ArrayList<Text>();
List<Text> grandparents = new ArrayList<Text>();
for (Text name : values) {
if (name.toString().trim().startsWith("child_")) {
grandchilds.add(new Text(name.toString().substring(6)));
} else if (name.toString().trim().startsWith("parent_")) {
grandparents.add(new Text(name.toString().substring(7)));
}
}
for (Text gchild : grandchilds) {
for (Text gparent : grandparents) {
context.write(gchild, gparent);
}
}
}
}输出结果为:
Jone
Jesse
Jone Alice
Tom Jesse
Tom Alice
Tom Ben
Tom Mary
Jone Ben
Jone Mary
Terry Jack
Terry Lucy
标签:mapreduce
原文地址:http://blog.csdn.net/gladyoucame/article/details/41455713