我正在尝试提出一种算法,在地图缩减中执行以下操作。我收到了一堆对象和所有者的用户ID。换句话说,我收到了很多对:
(object, uid)
我希望最终得到一对(object,count)
对,其中count
指的是对象在列表中出现的次数。需要注意的是,我们需要按如下方式过滤所有内容:
我们应该只包含对象对,以便至少为n
个不同的uid重复该对象。
我们应该只包含对象,使其重复的总次数至少为m。
对象和用户都表示为整数。问题是将每个(object,uid)
对转换为(object, 1)
然后通过对第二个整数求和来将它们一起减少是微不足道的。然后,我可以过滤掉未达到(2)阈值的所有内容。但是,在这一点上,我会失去过滤(1)所需的信息,这是我不知道如何融入其中的。有人有什么建议吗?
答案 0 :(得分:0)
最简单,最自然的方法是按顺序运行两个MR作业。第一项工作的目标是计算每个object
每个uid
拥有的次数。结果是三元组(object
,uid
,count
)。此处的uid
字段仅用于调试目的 - 在第二个作业中不需要它。第二个职位组由object
组成三元组。在每次reduce()调用结束时,您都知道:
uid
s的数量(已接收的三元组的数量)object
的时间总数(count
字段的总和)所以,现在你可以应用两个过滤器。
单作业设置也是可行的,但它需要使用setSortComparatorClass(),setGroupingComparatorClass()和setPartitionerClass()来处理较低级别的作业。想法是map()应该发出包含object
和uid
字段的复合键,根本不使用值(NullWritable):
object
字段对密钥进行分区。这可以保证具有相同object
的所有记录将转到相同的reduce任务。object
字段,如果它们相同,则uid
字段。object
字段进行比较。在结果中,单个reduce任务的输入如下所示:
object1 uid1
object1 uid2
object1 uid2
object1 uid2
object1 uid5
object1 uid6
object1 uid6
------------ <- boundary of call to reduce
object7 uid1
object7 uid1
object7 uid5
------------- <-- boundary of call to reduce()
object9 uid3
正如您所看到的,uid在每次调用reduce()时都是严格排序的,这允许您同时计算不同和非不同uid的数量。