3

我有以下文件作为输入,它由 10000 行组成,如下所示

250788965731,20090906,200937,200909,621,SUNDAY,WEEKEND,ON-NET,MORNING,OUTGOING,VOICE,25078,PAY_AS_YOU_GO_PER_SECOND_PSB,SUCCESSFUL-RELEASEDBYSERVICE,5,0,1,6.25,635-10-104-40163. 

如果第 18 列小于 10 并且第 9 列是早上,我必须打印第一列。我做了以下代码。我没有得到输出。输出文件为空。

public static class MyMap extends Mapper<LongWritable, Text, Text, DoubleWritable> {


    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String line = value.toString();
        String[] day=line.split(",");
        double day1=Double.parseDouble(day[17]);
        if(day[8]=="MORNING" && day1<10.0)
        {
        context.write(new Text(day[0]),new DoubleWritable(day1));
        }
    }
}
public static class MyReduce extends Reducer<Text, DoubleWritable, Text,DoubleWritable> {

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

        String no=values.toString();
        double no1=Double.parseDouble(no);
        if(no1>10.0)
        {
        context.write(key,new DoubleWritable(no1) );
        }

    }
}

请告诉我我做错了什么?流量是否正确?

4

2 回答 2

3

我可以看到一些问题。

首先,在您的Mapper, 您应该在比较s时使用.equals()而不是。否则,您只是在比较引用,即使对象内容相同,比较也会失败。由于 Java String 实习,它可能会成功,但如果这是最初的意图,我会避免过分依赖它。==StringString

在您的Reducer中,我不确定您想要实现什么,但无论如何我都可以发现一些错误的事情。输入键是Iterable<DoubleWritable>,因此您应该对其进行迭代并对每个单独的值应用您需要的任何条件。这是我将如何重写您的Reducer

public static class MyReduce extends Reducer<Text, DoubleWritable, Text,DoubleWritable> {

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

        for (DoubleWritable val : values) {
             if (val.get() > 10.0) {
                 context.write(key, val);
             }
        }
    }
}

但整体逻辑没有多大意义。如果您只想在第 18 列小于 10 且第 9 列为 时打印第一列MORNING,那么您可以使用 aNullWritable作为映射器的输出键,并将第 1 列写day[0]为输出值。Reducer在这种情况下,您可能甚至不需要 ,您可以使用job.setNumReduceTasks(0);.

让我思考的一件事是,如果您的输入只有 10k 行,您真的需要 Hadoop 工作吗?在我看来,一个简单的 shell 脚本(例如 with awk)对于这个小数据集就足够了。

希望有帮助!

于 2013-01-12T21:19:07.370 回答
0
  1. 我相信这是一个映射器唯一的工作,因为您的数据已经具有您想要检查的值。
  2. 您的映射器已发出值,day1 < 10.0而您的减速器仅发出值,即。day1 > 10.0因此,您的减速器不会输出任何值。

所以我认为你的减速器应该是这样的:

String no=values.toString();
double no1=Double.parseDouble(no);
if(no1 < 10.0)
{
context.write(key,new DoubleWritable(no1) );
}

我认为这应该得到你想要的输出。

于 2013-01-13T09:10:19.603 回答