情况
我正在尝试输出一个倒排索引,其中术语作为键,文档编号:频率作为值。值列表按频率降序排列。理想情况下,我只想用 1 个 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;
}
组合比较器.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());
}