Hadoop Mapreduce将值链接到每个键的列表中

Hadoop Mapreduce将值链接到每个键的列表中,hadoop,mapreduce,Hadoop,Mapreduce,我有一个小项目,我在mapreduce做,因为我是新的,我遇到了很多困难,所以我会感谢帮助。 在这个项目中,我有一个包含站点和标签的文件(每个站点有10个标签),我想通过共享标签为每个站点找到相似的站点。 以3个站点为例,这是我的数据集 site1 tag1 site1 tag2 site1 tag3 site1 tag4 site1 tag5 site2 tag1 site2 tag2 site2 tag3 site2 tag11 site2 tag12

我有一个小项目,我在mapreduce做,因为我是新的,我遇到了很多困难,所以我会感谢帮助。 在这个项目中,我有一个包含站点和标签的文件(每个站点有10个标签),我想通过共享标签为每个站点找到相似的站点。 以3个站点为例,这是我的数据集

site1   tag1
site1   tag2
site1   tag3
site1   tag4
site1   tag5
site2   tag1
site2   tag2
site2   tag3
site2   tag11
site2   tag12
site3   tag1
site3   tag11
site3   tag13
site3   tag14
site3   tag15
(对于这个例子,我只为每个站点创建了5个)。 我想做的是做一个mapreduce,它的关键是站点的标签和值。 我想让每个标签都得到一个包含这个标签的站点的列表(或数组或任何东西) 所以在这个例子中:

tag1: site1, site2, site3
tag2: site1,site2
tag3: site1, site2
tag4: site1 
等等 然后浏览列表,对于每一个公共对,在其旁边给出一个值1,如下所示

tag1: site1_site2 1, site1_site3 1, site2_site3 1
tag2: site1_site2 1
等等 然后链接另一个mapreduce作业,对每一对的值求和 我为此写了这段代码

public static class TokenizerMapper extends Mapper<Object, Text, Text, Text>{

    private Text site = new Text();
    private Text tag = new Text();
    public void map(Object key, Text value, Context context) 
                       throws IOException, InterruptedException {
        StringTokenizer itr = new StringTokenizer(value.toString(), "\t");
        while (itr.hasMoreTokens()) {
            site.set(itr.nextToken());
            tag.set(itr.nextToken());
            context.write(tag, site);
        }
    }
}

public static class tagCount extends Reducer<Text,IntWritable,Text,Text> {

    public void reduce(Text key, Iterable<Text> values, Context context) 
                             throws IOException, InterruptedException {
        String res = "";
        while (values.iterator().hasNext()) {
            res = res + "," + values.iterator().next();
        }
        Text result = new Text(res);
        context.write(key, result);
    }
}

public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    Job job = Job.getInstance(conf, "tag count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(tagCount.class);
    job.setReducerClass(tagCount.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(Text.class);
    FileInputFormat.addInputPath(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
}
等等 我试图设置一个字符串,当我迭代值向字符串添加下一个标记时,它不起作用


提前非常感谢您的帮助

以下是您的减速机的重述,以帮助您开始:

public static class TagCount extends Reducer<Text,IntWritable,Text,IntWritable> {

    private IntWritable one = new IntWritable(1);
    private Text out = new Text();

    public void reduce(Text key, Iterable<Text> values, Context context) 
                         throws IOException, InterruptedException {

        List<String> sites = new ArrayList<String>();
        for (Text t : values) {
            sites.add(t.toString());
        }

        for (int i=0; i<sites.size()-1; i++) {
            for (int j=i+1; j<sites.size(); j++) {
                out.set(sites.get(i) + "_" + sites.get(j))
                context.write(out, one);
            }
        }
    }
}
公共静态类标记计数扩展{
私有IntWritable one=新的IntWritable(1);
私有文本输出=新文本();
公共void reduce(文本键、Iterable值、上下文)
抛出IOException、InterruptedException{
列表站点=新建ArrayList();
对于(文本t:值){
添加(t.toString());
}

对于(int i=0;为了使我的问题更具体,我想知道如何迭代reducer中某个键的所有值。好的,我实际上发现我的代码甚至没有进入reducer函数,只有map函数:(Remove
job.setCombinerClass(tagCount.class)
。您不想为此使用组合器。我删除了它,但我认为没有任何更改,它仍然由于某种原因没有进入reducer函数。(尝试从中打印内容,但没有打印内容)调试不会进入它发现它没有进入reducer的原因我使用了错误的扩展名忘记了将可写入文本保存为:)您好,谢谢您的帮助,它真的推动了我前进。我写了您所说的,当我在控制台中调试它时,它工作得很好,但当我查看文件时,由于某种原因,它是空的。for中的write不工作或覆盖了它自己,我想确保您有
作业。setOutputValueClass(IntWritable.class)
首先,我真的很想说谢谢你抽出时间来帮助我,我非常感谢。我很想听听你的评论,所以请把它写在answer@Binary中
public static class TagCount extends Reducer<Text,IntWritable,Text,IntWritable> {

    private IntWritable one = new IntWritable(1);
    private Text out = new Text();

    public void reduce(Text key, Iterable<Text> values, Context context) 
                         throws IOException, InterruptedException {

        List<String> sites = new ArrayList<String>();
        for (Text t : values) {
            sites.add(t.toString());
        }

        for (int i=0; i<sites.size()-1; i++) {
            for (int j=i+1; j<sites.size(); j++) {
                out.set(sites.get(i) + "_" + sites.get(j))
                context.write(out, one);
            }
        }
    }
}