我有2个输入文件用于Hadoop MapRed任务。
该计划的输入为input.txt
,其中包含每行PaperID keyword1 keyword2 FieldID
p20 k j f3
p21 k j f11
p22 k j f3
p23 k j f2
p23 k j f1
Reducer类中使用的文件sammap.txt
包含在每行FieldID FieldName
f1 AI
f2 DB
f3 DB
f4 AI
代码如下: 包多拉多;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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;
public class Dorado {
public static class TokenizerMapper
extends Mapper<Object, Text, Text, Text>{
private Text word = new Text();
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
String str = value.toString().replaceAll(" +", " ").trim(), fir="", lst="";
if (!str.equals("")) {
fir = str.substring(0, str.indexOf(" "));
lst = str.substring(str.lastIndexOf(" ")+1);
context.write(new Text(fir), new Text(lst));
}
}
}
public static class IntSumReducer
extends Reducer<Text,Text,Text,Text> {
// private IntWritable result = new IntWritable();
private HashMap<Text, Text> fieldToClass = new HashMap<>();
public void reduce(Text key, Iterable <Text> value,Context context) throws IOException, InterruptedException {
FileReader fr = new FileReader("sammap.txt");
BufferedReader br = new BufferedReader(fr);
String str=null;
while ((str = br.readLine()) != null) {
String st[] = str.split(" +");
fieldToClass.put(new Text(st[0].trim()), new Text(st[1].trim()));
//System.out.println("--"+st[0].trim()+"--"+ st[1].trim()+"--");
}
fr.close();
for (Text field : value) {
System.out.println(key + "-->" + field);
if (fieldToClass.containsKey(field))
context.write(key, fieldToClass.get(field));
}
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "dorado");
job.setJarByClass(Dorado.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
Hashmap fieldToClass
的关键字为FieldID,值为FieldName。
控制台上的输出,用于Reducer类中的以下代码段:
for (Text field : value) {
System.out.println(key + "-->" + field);
if (fieldToClass.containsKey(field))
context.write(key, fieldToClass.get(field));
}
就是这样:
p20-->DB
p22-->DB
p23-->AI
p23-->DB
但是我们希望输出格式为:
p20-->f3
p22-->f3
p23-->f1
p23-->f2
此程序的最终输出文件中也没有输出。该文件为空。
我们在文件中期望的正确输出是:
p20 DB
p22 DB
p23 DB
p23 AI
为什么程序行为错误?有哪些可能的解决方案?
答案 0 :(得分:1)
您的整个过程可以在映射器内部完成。使用mapper的setup函数初始化HashMap。直接在HashMap中搜索fieldId并获取它的值并将其写入上下文。在可迭代值的for循环内的reducer中输出相同的东西。