Java MapReduce通过2个字段转换为时间幻灯片

问题描述

我有以下输入内容

{"start_time": 1,"end_time" 3,"app_name": "app1"}
{"start_time": 2,"end_time" 4,"app_name": "app2"}
{"start_time": 3,"end_time" 5,"app_name": "app1"}
{"start_time": 3,"app_name": "app2"}
{"start_time": 10,"end_time" 12,"app_name": "app1"}
{"start_time": 15,"end_time" 17,"app_name": "app2"}

我需要将每个应用程序的输入转换为时间范围吗? 输出应如下所示:

{app1,[{1,5},{10,12},app2 [{2,{15,17}]]

我考虑过要使用mapreduce,但是我不确定如何... 有任何想法吗? 谢谢

解决方法

以下仅是一种可能的解决方案,不能保证是最佳的。

更新This is a demo I wrote for clarification. If people who see this have a better idea of improving,please tell me via github issues.

一开始,我们可以将问题分为三个部分:

  1. 将map-reduce视为返回键值结果序列,那么这个问题的关键是什么?
  2. 如何在地图部分期间设计返回类型?
  3. 已映射时如何减少?

不言而喻,第0个问题的答案是app。因此,我们将输入分为两部分,一部分用于app1,另一部分用于app2。而且我们只研究了一部分,例如app2,因为这一部分比app1复杂一点。

在设计map函数时,应注意该类型必须易于还原,同时自然显示结果。考虑到结果,它以List<Pair>的形式显示。因此,第一个问题的答案是List<Pair>

因此,我们使用mapToPair(app,[(begin,end)])的形式映射输入的每一行。然后我们只考虑如何减少。

事情变得简单。归约过程本身就是一个经典问题-间隔合并,最经典的解决方案是O(nlogn)算法。但是这个问题是另一个版本,因为当减少时,列表本身自然地在两侧排序。因此可以省略排序部分,从而导致一种O(n+m)单遍合并排序算法。尝试将此算法应用于app2,即可成功。

副作用是,同时创建了ListPair。一种可能的方法是使用可变设计,当省略冗余对时,适当地收集它们,而在需要创建新对时,只需使用收集的对即可。