场合
我正在尝试输出一个带有术语作为键和文档编号的反向索引:frequency作为值。值列表按频率按降序排序。理想情况下,我只想做一个Mapreduce阶段/工作。
term1 -> (doc3, 2) (doc1, 1) (doc5, 1)
term2 -> (doc2, 3) (doc3, 2) (doc6, 1)
我尝试过什么
我的程序现在的工作方式是我创建一个复合键(term,docNum = count,freq = 1)并创建一个自然值(docNum = count,freq = 1)。我从MAP传递了这些键值对。在组合期间,我总结频率并将总和作为复合键和自然值的新频率值传递。最后,在reduce阶段,我输出键和值列表。
问题
对于我的复合键,我设置了比较器,以便按降序对频率进行排序。但是,我最初将术语频率传递为1(这样我就可以在组合阶段将它们相加)。似乎二级排序比较在组合之前发生。在总和频率之后,不是比较频率值,而是在求和之前进行比较。所以在上面的例子中,term2 - >将doc2的频率1与term2 - >进行比较。 doc2的频率为1而不是term2 - >将doc2的频率3与term2进行比较 - > doc3的频率为2.
我不知道如何让频率按降序排序。
CompositeKey.java(compareTo)
@Override
public int compareTo(TermCompositeKey termCompositeKey) {
int result = this.term.compareTo(termCompositeKey.getTerm());
if (result == 0) {
this.tf.compareTo(termCompositeKey.getTf());
}
return result;
}
CombinerComparator.java
public class TermCombinerComparator extends WritableComparator {
protected TermCombinerComparator() {
super(TermCompositeKey.class, true);
}
@SuppressWarnings("rawtypes")
@Override
public int compare(WritableComparable wc1, WritableComparable wc2) {
int result = 0;
TermCompositeKey termCompositeKey1 = (TermCompositeKey) wc1;
TermCompositeKey termCompositeKey2 = (TermCompositeKey) wc2;
result = termCompositeKey1.getTerm().compareTo(termCompositeKey2.getTerm());
if (result == 0) {
result= (int)(termCompositeKey1.getDocPosition() - termCompositeKey2.getDocPosition());
}
return result;
}
GroupingComparator.java
public class TermGroupingComparator extends WritableComparator {
protected TermGroupingComparator() {
super(TermCompositeKey.class, true);
}
@SuppressWarnings("rawtypes")
@Override
public int compare(WritableComparable wc1, WritableComparable wc2) {
TermCompositeKey termCompositeKey1 = (TermCompositeKey) wc1;
TermCompositeKey termCompositeKey2 = (TermCompositeKey) wc2;
return termCompositeKey1.getTerm().compareTo(termCompositeKey2.getTerm());
}