0

假设我有三个基本模型:用户、公司和访问。每次用户去公司时,都会以这种格式记录一次访问(user_id, company_id, visit_date)

我希望能够计算公司访问之间的平均时间。不是总体访问量,而是具体而言,他们的一位顾客在返回商店之前平均等待多长时间。

例如,如果一位用户在周二、周三和周五访问,则给出一天的“间隙”和两天的“间隙” => (1, 2)。如果另一个用户在周一和周五访问,则有 4 天的间隔 => (4)。如果第三个用户只访问过一次,则不应考虑他。公司用户访问的平均时间为 (1 + 2 + 4) / 3 = 2.333 天。

如果我有成千上万的用户、水龙头和公司,我想为每家公司计算一个数字,我应该怎么做?我以前只做过基本的 MapReduce 应用程序,我不知道我的 Map 和 Reduce 步骤是什么来完成这项工作。任何人都可以帮我找出伪代码中的 MapReduce 吗?还是有其他一些我可以合理执行的分布式计算方法?作为记录,我想每晚对我的数据库执行此操作。

4

1 回答 1

0

过于简单的方法是有两个工作步骤。

第一个工作步骤有一个映射器,以“company:user”和“visit_date”的形式写入键值。在上面的示例中,映射器将编写如下内容:

"user1:companyA" -> "2012/07/16"
"user1:comapnyA" -> "2012/07/17"
"user1:comapnyA" -> "2012/07/19"
"user2:comapnyA" -> "2012/07/15"
"user2:comapnyA" -> "2012/07/19"
...

这意味着对 reducer 的每次调用都会将单个用户的所有访问传递给单个公司。这意味着对 reducer 的一次调用将传入:

"user1:companyA" -> {2012/07/16, 2012/07/17, 2012/07/19}

另一个电话将传入:

"user2:companyA" -> {2012/07/15, 2012/07/19}

我假设日期集(作为 Iterable 值传入)在您对其进行排序时很容易管理,找出差距并以“公司”和“差距”的形式将每个差距的记录作为键值对写入. 例如,当通过时:

"user1:companyA" -> {2012/07/16, 2012/07/17, 2012/07/19}

第一个作业的减速器将写入上下文:

"companyA" -> 1
"compnayA" -> 2

第二个工作有一个传递映射器,它只是将公司/差距信息传递给减速器。对 reducer 的每次调用都会为特定公司提供一个可迭代的差距值。遍历数据以产生平均值并以“company”和“average_gap”的形式写入键值对。

如果原始访问集太大,我们可以讨论让 hadoop 使用一些自定义比较器为您进行排序。

于 2012-07-18T22:06:44.243 回答