使用阈值过滤对集合进行分组

时间:2016-12-06 21:10:03

标签: mapreduce

我正在尝试提出一种算法,在地图缩减中执行以下操作。我收到了一堆对象和所有者的用户ID。换句话说,我收到了很多对:

(object, uid)

我希望最终得到一对(object,count)对,其中count指的是对象在列表中出现的次数。需要注意的是,我们需要按如下方式过滤所有内容:

  1. 我们应该只包含对象对,以便至少为n个不同的uid重复该对象。

  2. 我们应该只包含对象,使其重复的总次数至少为m。

  3. 对象和用户都表示为整数。问题是将每个(object,uid)对转换为(object, 1)然后通过对第二个整数求和来将它们一起减少是微不足道的。然后,我可以过滤掉未达到(2)阈值的所有内容。但是,在这一点上,我会失去过滤(1)所需的信息,这是我不知道如何融入其中的。有人有什么建议吗?

1 个答案:

答案 0 :(得分:0)

最简单,最自然的方法是按顺序运行两个MR作业。第一项工作的目标是计算每个object每个uid拥有的次数。结果是三元组(objectuidcount)。此处的uid字段仅用于调试目的 - 在第二个作业中不需要它。第二个职位组由object组成三元组。在每次reduce()调用结束时,您都知道:

  1. 对象的不同uid s的数量(已接收的三元组的数量)
  2. 拥有object的时间总数(count字段的总和)
  3. 所以,现在你可以应用两个过滤器。

    单作业设置也是可行的,但它需要使用setSortComparatorClass()setGroupingComparatorClass()setPartitionerClass()来处理较低级别的作业。想法是map()应该发出包含objectuid字段的复合键,根本不使用值(NullWritable):

    1. 分区程序类仅使用密钥的object字段对密钥进行分区。这可以保证具有相同object的所有记录将转到相同的reduce任务。
    2. SortComparator类以这样的方式实现:首先它比较object字段,如果它们相同,则uid字段。
    3. GroupingComparatorClass仅使用object字段进行比较。
    4. 在结果中,单个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的数量。