有可能与所发射的价值简单的标签,因为只有三种类型的文件都参与其中。在地图中提取分割的路径,确定它的位置并为该值添加合适的前缀。为了清楚,说的输出在3个目录:
- 路径1/mr_out_1
- 路径2/mr_out_2
- path3时/ mr_out_3
使用TextInputForamt
所有这些路径,在map
你会做:
String[] keyVal = value.spilt("\t",2);
Path filePath = ((FileSplit) context.getInputSplit()).getPath();
String dirName = filePath.getParent().getName().toString();
Text outValue = new Text();
if(dirName.equals("mr_out_1")){
outValue.set("1_" + keyVal[1]);
} else if(dirName.equals("mr_out_2")){
outValue.set("2_" + keyVal[1]);
} else {
outValue.set("3_" + keyVal[1]);
}
context.write(new Text(keyVal[0]), outVal);
如果您将所有文件放在同一个目录中,请使用该文件名称而不是dirName。然后,找出基于名字的标志(一个正则表达式匹配可能是合适的):
String fileName = filePath.getName().toString();
if(fileName.matches("regex")){ ... }
在reduce
只是把传入值的列表和排序。休息很简单。
List<String> list = new ArrayList<String>(3);
for(Text v : values){
list.add(v.toString());
}
Collections.sort(list);
StringBuilder builder = new StringBuilder();
for(String s : list){
builder.append(s.substring(2)+"\t");
}
context.write(key, new Text(builder.toString().trim()));
我认为它会达到目的。请记住,如果有超过9个文件(由于字母顺序)Collection.sort
策略将失败。然后,您可以单独提取标签,将其转换为Integer
,然后使用TreeMap<tag, actualString>
进行排序。
注:以上所有段使用新的API。我没有使用IDE来写这些,所以很少有语法错误可能存在。再一次,我没有按照正确的书面惯例。说的map
的outKey可能是一个类的成员,并使用outKey.set(keyVal[0])
可以删除Text
对象创建开销。
也许二次排序和值(每个MR作业一个)手动前缀是你在找什么...看看(http://hadoop.apache.org/docs/r2.2.0/api /org/apache/hadoop/mapreduce/Reducer.html) – vefthym 2014-10-27 16:22:40
@vefthym感谢您的提示。我会仔细看看的!如果我能管理一些东西,我会让你知道的。 – tolgap 2014-10-27 16:56:37