我有一个场景。以前job1
的输出在下一个工作中,我需要找到具有最大值的i
密钥。例如i = 3,具有最大值的3个密钥。
(i
将是自定义参数)
如何解决这个问题。
我们应该在job2映射器中计算max
因为会有唯一键,因为输出来自之前的reducer
要么
在第二个作业reducer中找到max
。但是又如何查找i
个键?
更新
我试过这种方式 而不是在reducer中将值作为值发出。我将值作为键发出,因此我可以按升序获取值。 我写了下一个MR job.where mapper只是发出键/值。
Reducer找到key的最大值 但是我再次陷入困境,因为我们试图获取id,所以无法完成,因为id只是唯一的,值不是唯一的。
如何解决这个问题。
任何人都可以为此提出解决方案。
提前致谢。
答案 0 :(得分:1)
您可以使用i
找到热门PriorityQueue
密钥。简单的代码来说明这个想法:
public static class TopNMapper extends Mapper<IntWritable, DoubleWritable, IntWritable, DoubleWritable> {
private static class MyPair implements Comparable<MyPair> {
public final int key;
public final double value;
MyPair(int key, double value) {
this.key = key;
this.value = value;
}
@Override
public int compareTo(MyPair o) {
return -Double.compare(value, o.value); // i'm not sure about '-'
}
}
private final PriorityQueue<MyPair> topN = new PriorityQueue<MyPair>();
@Override
protected void map(IntWritable key, DoubleWritable value, Context context) throws IOException, InterruptedException {
if (Double.isNaN(value.get())) {
return; // not a number
}
topN.add(new MyPair(key.get(), value.get()));
if (topN.size() <= 50) { // simple optimization
return;
}
while (topN.size() > 3) { // retain only top 3 elements in queue
topN.poll();
}
}
@Override
protected void cleanup(Context context) throws IOException, InterruptedException {
while (topN.size() > 3) {
topN.poll(); // retain only top 3 elements in queue
}
for (MyPair myPair : topN) { // write top 3 elements
context.write(new IntWritable(myPair.key), new DoubleWritable(myPair.value));
}
}
}
如果你运行这个映射器(一个用于所有输入),你应该得到3个具有最大值的键。