java—使用某些数据类型作为mapreduce作业的输入

64jmpszr  于 2021-06-03  发布在  Hadoop
关注(0)|答案(1)|浏览(381)

我正在做一组mapreduce工作,将情节摘要列表转换为Map到movieid的每个单词的索引,以及使用了多少次。我有一个任务,它接受输入并创建一个节点的链接列表,其中包含单词、它来自的电影以及次数。我的第二个工作是使用这个linkedlist,并使用单词作为键,movieid和出现次数作为值,并将Map到每个电影的每个单词以及出现次数的索引吐出来。
调用fileinputformat.addinputpath()时,我可以使用path()或字符串,每个元素用逗号分隔。用linkedlist保存的所有数据创建一个庞大的字符串并不难,但是让Map程序使用linkedlist作为输入会更好。
我读过关于链接mapreduce作业的文章,所以请不要给我一个到yahoo开发者页面的链接。

zaqlnxep

zaqlnxep1#

在这里,您不需要两个mapreduce作业(或者一个linkedlist)。相反,我们可以将其视为字数计算的一个变体,但在输出中添加了电影ID列表。
Map输入:

354757\tToys come alive
432984\tMore toys

Map代码:

String[] idAndWords = input.split("\\t");

for(String word : idAndWords[1].split(" ")) {
    //Do whatever cleansing you want here - remove punctuation, lowercase etc.
    output.write(word,idAndWords[0]);
}

Map输出:

("toys","354757")
("come","354757")
("alive","354757")
("more","432984")
("toys","432984")

减速机代码:

//Maps movie IDs to occurrences
Map<String,Int> movieMap = new HashMap<>();
//In here is the list of movie IDs for each word
for(String val : values) {
    if(!movieMap.contains(val)) {
        movieMap.put(val,1);
    } else {
        movieMap.put(val,movieMap.get(val)+1);
    }
}
output.write(NullWritable.get(),key+"\t"+movieMap);

减速器输出:

toys\t[(3547571),(432984,1)]
come\t[(354757,1)]
alive\t[(354757,1)]
more\t[(432984,1)]

现在你不需要定制了 Writable 与我认为相当复杂的一套由两条锁链组成的乔布斯先生相比,这还不到十几条逻辑线。
效率扩展:
您可以通过向Map器输出中添加计数来提高效率—在当前实现中,绘图线“dog eat dog”将导致Map输出:

("dog","354757")
("eat","354757")
("dog","354757")

而您可以通过添加一个计数器并在输出前扫描整行,将其减少为两个记录:

("dog","354757\t2")
("eat","354757\t1")

我不想让我的例子变得更复杂,可读性降低,但是它的实现应该是微不足道的,并且应该可以很好地节省性能。

相关问题