복붙노트

[HADOOP] java Mapreduce를 사용하여 JSON 처리하기

HADOOP

java Mapreduce를 사용하여 JSON 처리하기

나는 hadoop mapreduce를 처음 사용합니다.

나는 데이터가 다음과 같이 저장된 텍스트 파일을 입력했다. 다음은 몇 가지 튜플 (data.txt)입니다.

{"author":"Sharīf Qāsim","book":"al- Rabīʻ al-manshūd"}
{"author":"Nāṣir Nimrī","book":"Adīb ʻAbbāsī"}
{"author":"Muẓaffar ʻAbd al-Majīd Kammūnah","book":"Asmāʼ Allāh al-ḥusná al-wāridah fī muḥkam kitābih"}
{"author":"Ḥasan Muṣṭafá Aḥmad","book":"al- Jabhah al-sharqīyah wa-maʻārikuhā fī ḥarb Ramaḍān"}
{"author":"Rafīqah Salīm Ḥammūd","book":"Taʻlīm fī al-Baḥrayn"}

이것은 (CombineBooks.java)에 코드를 작성 해야하는 Java 파일입니다.

package org.hwone;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.util.GenericOptionsParser;

//TODO import necessary components

/*
*  Modify this file to combine books from the same other into
*  single JSON object. 
*  i.e. {"author": "Tobias Wells", "books": [{"book":"A die in the country"},{"book": "Dinky died"}]}
*  Beaware that, this may work on anynumber of nodes! 
*
*/

public class CombineBooks {

  //TODO define variables and implement necessary components

  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    String[] otherArgs = new GenericOptionsParser(conf, args)
                .getRemainingArgs();
    if (otherArgs.length != 2) {
      System.err.println("Usage: CombineBooks <in> <out>");
      System.exit(2);
    }

    //TODO implement CombineBooks

    Job job = new Job(conf, "CombineBooks");

    //TODO implement CombineBooks

    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}

내 임무는“CombineBooks.java”에서 Hadoop 프로그램을 만드는 것입니다 "question-2"디렉토리에 반환됩니다. 프로그램에서해야 할 일 다음 : 입력 된 저자 책 튜플이 주어지면 map-reduce 프로그램은 모든 JSON 객체를 포함하는 JSON 객체를 생성해야합니다. JSON 배열에서 동일한 저자의 책, 즉

{"author": "Tobias Wells", "books":[{"book":"A die in the country"},{"book": "Dinky died"}]} 

어떻게 할 수 있습니까?

해결법

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

    1.먼저 작업하려는 JSON 객체를 사용할 수 없습니다. 이 문제를 해결하려면

    먼저 작업하려는 JSON 객체를 사용할 수 없습니다. 이 문제를 해결하려면

    다음으로, 코드의 첫 번째 줄은 "org.json"패키지를 만듭니다. 잘못된 경우, "my.books"와 같은 별도의 패키지를 만들어야합니다.

    셋째, 여기에서 결합기를 사용하는 것은 쓸모가 없다.

    다음은 내가 끝내었던 코드입니다. 문제를 해결하고 해결합니다.

    package my.books;
    import java.io.IOException;
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.LongWritable;
    import org.apache.hadoop.io.NullWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Job;
    import org.apache.hadoop.mapreduce.Mapper;
    import org.apache.hadoop.mapreduce.Reducer;
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
    import org.apache.hadoop.util.GenericOptionsParser;
    import org.json.*;
    
    import javax.security.auth.callback.TextInputCallback;
    
    public class CombineBooks {
    
        public static class Map extends Mapper<LongWritable, Text, Text, Text>{
    
            public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException{
    
                String author;
                String book;
                String line = value.toString();
                String[] tuple = line.split("\\n");
                try{
                    for(int i=0;i<tuple.length; i++){
                        JSONObject obj = new JSONObject(tuple[i]);
                        author = obj.getString("author");
                        book = obj.getString("book");
                        context.write(new Text(author), new Text(book));
                    }
                }catch(JSONException e){
                    e.printStackTrace();
                }
            }
        }
    
        public static class Reduce extends Reducer<Text,Text,NullWritable,Text>{
    
            public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException{
    
                try{
                    JSONObject obj = new JSONObject();
                    JSONArray ja = new JSONArray();
                    for(Text val : values){
                        JSONObject jo = new JSONObject().put("book", val.toString());
                        ja.put(jo);
                    }
                    obj.put("books", ja);
                    obj.put("author", key.toString());
                    context.write(NullWritable.get(), new Text(obj.toString()));
                }catch(JSONException e){
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String[] args) throws Exception {
            Configuration conf = new Configuration();
            if (args.length != 2) {
                System.err.println("Usage: CombineBooks <in> <out>");
                System.exit(2);
            }
    
            Job job = new Job(conf, "CombineBooks");
            job.setJarByClass(CombineBooks.class);
            job.setMapperClass(Map.class);
            job.setReducerClass(Reduce.class);
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(Text.class);
            job.setOutputKeyClass(NullWritable.class);
            job.setOutputValueClass(Text.class);
            job.setInputFormatClass(TextInputFormat.class);
            job.setOutputFormatClass(TextOutputFormat.class);
    
            FileInputFormat.addInputPath(job, new Path(args[0]));
            FileOutputFormat.setOutputPath(job, new Path(args[1]));
    
            System.exit(job.waitForCompletion(true) ? 0 : 1);
        }
    }
    

    내 프로젝트의 폴더 구조는 다음과 같습니다.

    src
    src/my
    src/my/books
    src/my/books/CombineBooks.java
    src/org
    src/org/json
    src/org/json/zip
    src/org/json/zip/BitReader.java
    ...
    src/org/json/zip/None.java
    src/org/json/JSONStringer.java
    src/org/json/JSONML.java
    ...
    src/org/json/JSONException.java
    

    입력은 다음과 같습니다

    [localhost:CombineBooks]$ hdfs dfs -cat /example.txt
    {"author":"author1", "book":"book1"}
    {"author":"author1", "book":"book2"}
    {"author":"author1", "book":"book3"}
    {"author":"author2", "book":"book4"}
    {"author":"author2", "book":"book5"}
    {"author":"author3", "book":"book6"}
    

    실행할 명령 :

    hadoop jar ./bookparse.jar my.books.CombineBooks /example.txt /test_output
    

    결과는 다음과 같습니다.

    [pivhdsne:CombineBooks]$ hdfs dfs -cat /test_output/part-r-00000
    {"books":[{"book":"book3"},{"book":"book2"},{"book":"book1"}],"author":"author1"}
    {"books":[{"book":"book5"},{"book":"book4"}],"author":"author2"}
    {"books":[{"book":"book6"}],"author":"author3"}
    

    세 가지 옵션 중 하나를 사용하여 org.json. * 클래스를 클러스터에 넣을 수 있습니다.

  2. ==============================

    2.분할 가능한 여러 줄 JSON을 참조하십시오. https://github.com/alexholmes/json-mapreduce

    분할 가능한 여러 줄 JSON을 참조하십시오. https://github.com/alexholmes/json-mapreduce

  3. from https://stackoverflow.com/questions/26659753/processing-json-using-java-mapreduce by cc-by-sa and MIT license