我有两个csv
个文件。一个人有(user_id, gameName,score)
,其他人有(user_id, age)
。如何使用地图缩减编程执行连接,以便我可以计算每个游戏的玩家的平均年龄。我不知道如何继续这个。
答案 0 :(得分:2)
您可以使用两个 MapReduce 作业来实现此目的。首先,加入两个数据集。第二,计算每场比赛球员的平均年龄。
将呼叫数据集(user_id ,gameName,score)
称为 GameSet
,将(user_id ,age)
称为 AgeSet
。
首先, JoinMapreduce 作业将为每个数据集分别设置两个映射器定义。这些映射器任务将输出user_id as key
和record as value
,并将标识符作为前缀添加到记录中。假设这个前缀对于第一个数据集是" game" ,对于第二个数据集是" age" 。这是识别Reducer
中的记录所必需的。 Reducer
将在列表中为每个键接收两个值(假设数据中没有重复项)。标识符将帮助我们识别记录,我们将创建一个new record
,其中包含有关用户的所有信息,例如gameName
,score
和age
。 reducer的输出将为gameName as key
和record as value
。 (如果你想优化那么你可以只发出用户的年龄。)
其次,第一个MapReduce作业的输出是GameName as Key
和Record as Value
。这将输入下一个 AvgAgePerGame MapReduce 作业。它将具有标识映射器,它将作为映射器输出发出输入。现在在reducer中,您将收到GameName as key
和list of records
(年龄列表)作为值。您可以将玩家的年龄相加并将其除以reduce方法中的玩家数量。输出密钥(GameName)和平均值。年龄作为价值。
答案 1 :(得分:1)
@YoungHobbit给出的答案是正确的。您可以通过ReduceSide joins
使用MutlipleInputFormat
和Chaining jobs
的组合来解决您的问题。
我已经为这个问题实现了整个MapReduce代码,可以在我的github repo here找到。
我们需要为我们需要加入的2个文件使用2个Mappers,即GameMapper和AgeMapper。这可以通过MultipleInputFormat
实现。
接下来,我们使用reducer连接两个映射器的数据,并将输出写入HDFS。这可以通过Reduce Side Joins
接下来,我们编写另一个MR作业,它使用前一个MR作业的输出作为输入。此映射器将游戏名称作为键发出,年龄作为每条记录的值。
最后写一个reducer,在那里进行逻辑以找出每个游戏的平均用户年龄。然后将输出写入HDFS。
在我的实现中,两个MR作业都是从一个Driver类调用的。这是通过Chaining Jobs
实现的。
有关我实现此问题的更多信息,请查看github repo here中的自述文件。