关系列表,【Mapreduce】利用单表关联在父子关系中求解爷孙关系"/>
php爷孙关系列表,【Mapreduce】利用单表关联在父子关系中求解爷孙关系
首先是有如下数据,设定左边是右边的儿子,右边是左边的父母
Tom Lucy
Tom Jack
Jone Lucy
Jone Jack
Lucy Mary
Lucy Ben
Jack Alice
Jack Jesse
Terry Alice
Terry Jesse
Philip Terry
Philip Alma
Mark Terry
Mark Alma要求输出如下所示的爷孙关系,左边是右边的孙子,右边是左边的祖父母:
TomJesse
TomAlice
JoneJesse
JoneAlice
JoneBen
JoneMary
TomBen
TomMary
PhilipAlice
PhilipJesse
MarkAlice
MarkJesse
要利用Mapreduce解决这个问题,主要思想如下:
1、在Map阶段,将父子关系与相反的子父关系,同时在各个value前补上前缀-与+标识此key-value中的value是正序还是逆序产生的,之后进入context。
下图通过其中的Jone-Lucy Lucy-Mary,求解出Jone-Mary来举例
2、MapReduce会自动将同一个key的不同的value值,组合在一起,推到Reduce阶段。在value数组中,跟住前缀,我们可以轻松得知,哪个是爷,哪个是孙。
因此对各个values数组中各个项的前缀进行输出。
可以看得出,整个过程Key一直被作为连接的桥梁来用。形成一个单表关联的运算。
因此代码如下,根据上面的思想很容易得出如下的代码了,需要注意的是,输出流输入流都要设置成Text,因为全程都是在对Text而不是IntWritable进行操作:
import java.io.IOException;
import java.util.ArrayList;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
public class MyMapReduce {
public static class MyMapper extends Mapper {
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
String child = value.toString().split(" ")[0];
String parent = value.toString().split(" ")[1];
//产生正序与逆序的key-value同时压入context
context.write(new Text(child), new Text("-" + parent));
context.write(new Text(parent), new Text("+" + child));
}
}
public static class MyReducer extends Reducer {
public void reduce(Text key, Iterable values, Context context)
throws IOException, InterruptedException {
ArrayList grandparent = new ArrayList();
ArrayList grandchild = new ArrayList();
for (Text t : values) {//对各个values中的值进行处理
String s = t.toString();
if (s.startsWith("-")) {
grandparent.add(new Text(s.substring(1)));
} else {
grandchild.add(new Text(s.substring(1)));
}
}
//再将grandparent与grandchild中的东西,一一对应输出。
for (int i = 0; i < grandchild.size(); i++) {
for (int j = 0; j < grandparent.size(); j++) {
context.write(grandchild.get(i), grandparent.get(j));
}
}
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args)
.getRemainingArgs();
if (otherArgs.length != 2) {
System.err.println("Usage: wordcount ");
System.exit(2);
}
Job job = new Job(conf);
job.setMapperClass(MyMapper.class);
job.setReducerClass(MyReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
// 判断output文件夹是否存在,如果存在则删除
Path path = new Path(otherArgs[1]);// 取第1个表示输出目录参数(第0个参数是输入目录)
FileSystem fileSystem = path.getFileSystem(conf);// 根据path找到这个文件
if (fileSystem.exists(path)) {
fileSystem.delete(path, true);// true的意思是,就算output有东西,也一带删除
}
FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
更多推荐
php爷孙关系列表,【Mapreduce】利用单表关联在父子关系中求解爷孙关系
发布评论