Как получить максимальное количество по двум ключам в java mapreduce hadoop - PullRequest
0 голосов
/ 01 мая 2018

У меня есть текстовый файл с 6 столбцами, и я заинтересован в третьем и четвертом столбце, Город и продукт, вот пример:

2015-01-01; 09: 00: 00; Нью-Йорк; обувь; 214.05; Amex>

Мне нужно получить продукт с максимальными продажами по городу. У меня уже есть код для агрегирования и подсчета всех продуктов по городам, вот код класса mapper и редуктора класса:

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class ContaMaxCidadeProdutoMapper extends Mapper<Object, Text, Text, IntWritable> {

	private final static Text cidadeproduto = new Text();
	private final static IntWritable numeroum = new IntWritable(1);

	public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
		
		String[] linha=value.toString().split(";");		
		cidadeproduto.set(linha[2] +" "+linha[3]);
		context.write(cidadeproduto, numeroum);		
	}
}

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class ContaMaxCidadeProdutoReducer extends	Reducer<Text, IntWritable, Text, IntWritable> {
	
	public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
		int contValue = 0;
		
		for (IntWritable value : values) {
			contValue += value.get();
		}
		
		context.write(key, new IntWritable(contValue));
	}
}

Правильно работает подсчет каждого продукта по городам, но теперь мне нужно получить продукт с максимальным количеством по городам. Я знаю, как получить продукт максимального количества всего набора данных, но я не знаю, как получить его по городам. Буду признателен за любые советы! Спасибо

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Вы хотите получить продукт с максимальным количеством по городу . Как я понимаю, вы хотите, чтобы в каждом городе был продукт, с максимальными продажами в этом конкретном городе, не так ли?

Я бы предпочел сделать это в 2 парах M-R. Первая пара похожа на вашу:

public void map(Object key, Text value, Context context) {
    String[] linha = value.toString().split(";");       
    cidadeproduto.set(linha[2] + "&" + linha[3]);
    context.write(cidadeproduto, new IntWritable(1));       
}

public void reduce(Text key, Iterable<IntWritable> values, Context context){
    int contValue = 0;

    for (IntWritable value : values) {
        contValue += value.get();
    }
    context.write(key, new IntWritable(contValue));
}

И вторая пара.
Картограф будет перегруппировать ваши данные так, чтобы город был ключевым, а product & count - значением:

public void map(Object key, Text value, Context context) {
    String[] row = value.toString().split(";");
    String city = row[0].split("&")[0];
    String product = row[0].split("&")[1];
    String count = row[1];
    context.write(new Text(city), new Text(product + "&" + count));     
}

И затем уменьшение будет поддерживать максимальное значение для каждого города:

public void reduce(Text key, Iterable<Text> values, Context context){
    int maxVal = Integer.MIN_VALUE;
    String maxProd = "None";

    for (IntWritable value : values) {
        String ss = value.toString().split("&");
        int cnt = Integer.parseInt(ss[1]);
        if(cnt > maxVal){
            maxVal = cnt;
            maxProd = ss[0];
        }
    }
    context.write(key, new Text(maxProd));
}
0 голосов
/ 01 мая 2018

Я начну с объяснения основ карты / сокращения, из которых есть две основные части:

  • Карта: преобразуйте исходные данные в значение, с которым вы можете работать (в вашем случае, пара город / продукт и число)
  • Уменьшение: для каждой пары город / продукт сложите все числа.

В вашем текущем приложении вы выбрали номер 1, независимо от того, как выглядит вход. Суммирование группы 1с имеет тот же эффект, что и их подсчет.

Вместо этого вы захотите сопоставить его с другим значением, извлекая его из входной строки и анализируя его в Double, и отправляя его вместо numeroum.

...