如何在map reduce中按降序对数据进行排序?
How to sort data in descending order in map reduce?
我的 reducer 给出了这个 o/p
Country-Year,Medals
India-2008,60
United States-2008,1237
Zimbabwe-2008, 2
Namibia-2009,22
China-2009,43
United States-2009,54
我想要这个,应该根据奖牌进行排序,并且应该显示前三名。
Country-Year,Medals
United States-2008,1237
India-2008,60
United States-2009,54
有人建议我在自定义记录阅读器中进行排序(据了解它用于映射器部分),我浏览了一些资源但找不到太多关于排序的信息。请分享任何想法或 link 资源。提前致谢!
您可以实施 Map Reduce Top K 设计模式来实现您的 objective。
Top K 设计模式将根据值对您的记录进行排序并选择前 k 条记录。
您可以通过 this link 在您的数据上实施 Top K 设计模式。
当您在 Reducer 中聚合映射器的结果时 class 而不是将其写入输出,将其放入映射中,然后对映射进行排序并相应地显示结果。
键 = 国家-年份,值 = 奖牌
展示如何实现的虚拟代码
public class Medal_reducer extends Reducer<Text,IntWritable, Text , IntWritable> {
// Change access modifier as per your need
public Map<String , Integer > map = new HashMap<String , Integer>();
public void reduce(Text key , Iterable<IntWritable> values ,Context context )
{
// write logic for your reducer
// Enter reduced values in map for each key
for (IntWritable value : values ){
// calculate count
}
map.put(key.toString() , count);
}
public void cleanup(Context context){
//Cleanup is called once at the end to finish off anything for reducer
//Here we will write our final output
Map<String , Integer> sortedMap = new HashMap<String , Integer>();
sortedMap = sortMap(map);
for (Map.Entry<String,Integer> entry = sortedMap.entrySet()){
context.write(new Text(entry.getKey()),new IntWritable(entry.getValue()));
}
}
public Map<String , Integer > sortMap (Map<String,Integer> unsortMap){
Map<String ,Integer> hashmap = new HashMap<String,Integer>();
int count=0;
List<Map.Entry<String,Integer>> list = new LinkedList<Map.Entry<String,Integer>>(unsortMap.entrySet());
//Sorting the list we created from unsorted Map
Collections.sort(list , new Comparator<Map.Entry<String,Integer>>(){
public int compare (Map.Entry<String , Integer> o1 , Map.Entry<String , Integer> o2 ){
//sorting in descending order
return o2.getValue().compareTo(o1.getValue());
}
});
for(Map.Entry<String, Integer> entry : list){
// only writing top 3 in the sorted map
if(count>2)
break;
hashmap.put(entry.getKey(),entry.getValue());
}
return hashmap ;
}
}
希望这会有所帮助。
我的 reducer 给出了这个 o/p
Country-Year,Medals
India-2008,60
United States-2008,1237
Zimbabwe-2008, 2
Namibia-2009,22
China-2009,43
United States-2009,54
我想要这个,应该根据奖牌进行排序,并且应该显示前三名。
Country-Year,Medals
United States-2008,1237
India-2008,60
United States-2009,54
有人建议我在自定义记录阅读器中进行排序(据了解它用于映射器部分),我浏览了一些资源但找不到太多关于排序的信息。请分享任何想法或 link 资源。提前致谢!
您可以实施 Map Reduce Top K 设计模式来实现您的 objective。
Top K 设计模式将根据值对您的记录进行排序并选择前 k 条记录。
您可以通过 this link 在您的数据上实施 Top K 设计模式。
当您在 Reducer 中聚合映射器的结果时 class 而不是将其写入输出,将其放入映射中,然后对映射进行排序并相应地显示结果。
键 = 国家-年份,值 = 奖牌 展示如何实现的虚拟代码
public class Medal_reducer extends Reducer<Text,IntWritable, Text , IntWritable> {
// Change access modifier as per your need
public Map<String , Integer > map = new HashMap<String , Integer>();
public void reduce(Text key , Iterable<IntWritable> values ,Context context )
{
// write logic for your reducer
// Enter reduced values in map for each key
for (IntWritable value : values ){
// calculate count
}
map.put(key.toString() , count);
}
public void cleanup(Context context){
//Cleanup is called once at the end to finish off anything for reducer
//Here we will write our final output
Map<String , Integer> sortedMap = new HashMap<String , Integer>();
sortedMap = sortMap(map);
for (Map.Entry<String,Integer> entry = sortedMap.entrySet()){
context.write(new Text(entry.getKey()),new IntWritable(entry.getValue()));
}
}
public Map<String , Integer > sortMap (Map<String,Integer> unsortMap){
Map<String ,Integer> hashmap = new HashMap<String,Integer>();
int count=0;
List<Map.Entry<String,Integer>> list = new LinkedList<Map.Entry<String,Integer>>(unsortMap.entrySet());
//Sorting the list we created from unsorted Map
Collections.sort(list , new Comparator<Map.Entry<String,Integer>>(){
public int compare (Map.Entry<String , Integer> o1 , Map.Entry<String , Integer> o2 ){
//sorting in descending order
return o2.getValue().compareTo(o1.getValue());
}
});
for(Map.Entry<String, Integer> entry : list){
// only writing top 3 in the sorted map
if(count>2)
break;
hashmap.put(entry.getKey(),entry.getValue());
}
return hashmap ;
}
}
希望这会有所帮助。