복붙노트

[HADOOP] 어떻게 하둡에서 사용자 정의 출력 형식을 만들 수 있습니다

HADOOP

어떻게 하둡에서 사용자 정의 출력 형식을 만들 수 있습니다

나는 디렉토리에 여러 파일을 읽고 각 단어의 주파수를 출력하는 단어 카운트 하둡 프로그램의 변화를 만들려고하고 있습니다. 문제는 내가 출력에서왔다되는 파일 이름 뒤에 단어와 해당 파일의 주파수를 원하는 것이다. 예를 들어 :

word1
( file1, 10)
( file2, 3)
( file3, 20)

그래서 word1을 위해 (단어 "와"말). 그것은 FILE1, 요법 파일 2의 3 배이며, 그것을 10 배를 발견한다. 지금 그것은 단지 키 값 쌍을하고 출력하기됩니다

 StringTokenizer itr = new StringTokenizer(chapter);
  while (itr.hasMoreTokens()) {
    word.set(itr.nextToken());

    context.write(word, one);

나는하여 파일 이름을 얻을 수 있습니다

String fileName = ((FileSplit) context.getInputSplit()).getPath().getName();

하지만 내가 원하는 방식으로 포맷하는 방법을 이해하지 않습니다. 나는 OutputCollector에 찾아 봤는데,하지만 난 그것을 정확하게 사용하는 방법에 대한 확신입니다.

편집 : 이것은 내 매퍼 및 감속기입니다

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

private Text word = new Text();

public void map(Object key, Text value, Context context
                ) throws IOException, InterruptedException {

  //Take out all non letters and make all lowercase
  String chapter = value.toString();
  chapter = chapter.toLowerCase();
  chapter = chapter.replaceAll("[^a-z]"," ");

  //This is the file name
  String fileName = ((FileSplit) context.getInputSplit()).getPath().getName();

  StringTokenizer itr = new StringTokenizer(chapter);
  while (itr.hasMoreTokens()) {
    word.set(itr.nextToken());

   context.write(word, new Text(fileName)); //
  }
}
  }


  public static class IntSumReducer
       extends Reducer<Text,Text,Text,Text> { second


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

  Map<String, Integer> files = new HashMap<String, Integer>();

 for (Text val : values) {
    if (files.containsKey(val.toString())) {
        files.put(val.toString(), files.get(val.toString())+1);
    } else {
        files.put(val.toString(), 1); 
    }
}

String outputString="";

for (String file : files.keySet()) { 
    outputString = outputString + "\n<" + file + ", " + files.get(file) + ">"; //files.get(file)
}

context.write(key, new Text(outputString));
}

  }

이 단어 "는"예를 들어 대한 출력한다 :

a   
(
(chap02, 53), 1)
(
(chap18, 50), 1)

나는 그것 만드는 키 값이 각 항목의 값 1에 대한 키 쌍을 왜 확신입니다.

해결법

  1. ==============================

    1.난 당신이 모든이에 대한 사용자 정의 출력 형식을 필요가 있다고 생각하지 않습니다. 그래서 당신이 감속기에 따라 파일 이름을 통과, 당신은 단순히 당신이 TextOutputFormat 유형 작업에서 사용하는 문자열을 수정하여이 작업을 수행 할 수 있어야합니다. 설명은 다음과 같습니다.

    난 당신이 모든이에 대한 사용자 정의 출력 형식을 필요가 있다고 생각하지 않습니다. 그래서 당신이 감속기에 따라 파일 이름을 통과, 당신은 단순히 당신이 TextOutputFormat 유형 작업에서 사용하는 문자열을 수정하여이 작업을 수행 할 수 있어야합니다. 설명은 다음과 같습니다.

    매퍼에서 파일 이름을 얻고, 아래와 같은 textInputFormat에 추가

    String fileName = ((FileSplit) context.getInputSplit()).getPath().getName();
    context.write(key,new Text(fileName));
    

    그런 다음 감속기에 다음과 같은 일을 할 :

    public void reduce(Text key, Iterable<Text> values, Context context)
            throws IOException, InterruptedException {
        Map<String, Integer> files = new HashMap<String, Integer>();
        for (Text val : values) {
            if (files.containsKey(val.toString())) {
                files.put(val.toString(), files.get(val.toString()) + 1);
            } else {
                files.put(val.toString(), 1);
            }
        }
    
        String outputString = key.toString();
    
        for (String file : files.keySet()) {
            outputString += "\n( " + file + ", " + files.get(file) + ")";
        }
    
        context.write(key, new Text(outputString));
    }
    

    이 감속기는 정확하게 당신이 원하는 수의 표시 형식을 강제하기 위해, 모든 라인의 시작 부분에 "\ n을"을 추가합니다.

    이것은 자신의 outputformat를 쓰는 것보다 훨씬 간단 보인다.

  2. from https://stackoverflow.com/questions/29612503/how-to-create-a-custom-output-format-in-hadoop by cc-by-sa and MIT license