使用 MapReduce 和 Hive 进行数据分析(2)

实验-在电影库中查找演员合作次数最多的演员及其合作作品

【实验要求】

-(1)结合本门课程学过的知识,编写程序(Java程序/MapReduce)对’Film.json’内容进行筛选,筛选出只包含你的演员演过的电影,并转换为 csv 格式。

-(2)把转换后csv文件导入 Hive,使用 SQL 查询和我的演员合作次数最多的前5位演员及其合作最高分的作品(如果同分则优先列出年份较近的,例如2000年上映的A电影和1995年上映的B电影同分,则排序应该为A,B)。需要展示演员姓名,合作次数,以及合作最高分的作品名称和评分。

【提示1 JSON 转换 CSV 格式】

  • 实验(1)已经提示了如何把 JSON 格式转换为 Java 的对象。这里JSON可以先转换为 Java 对象,再转换为CSV。CSV的格式非常简单,使用分行符表示1行数据,每个单元数据使用英文的逗号,隔开。

  • 在转换的过程中,我们可以考虑只筛选有我的演员参演的电影。参考代码如下:

    String actor="我的演员姓名";
    // 获取 Film.json 文件的绝对路径
    String filmJsonPath=Json2Csv.class.getClassLoader().getResource("Film.json").getPath();
     
    //读取Film.json
    BufferedReader br=new BufferedReader(new FileReader(filmJsonPath));
     
    //MovieInfo 类可以参考实验1
    MovieInfo m=null;
    String line;
    while((line=br.readLine())!=null){
    //Fastjson 把每行的json 字符串转换为对象。
    m= JSON.parseObject(line,MovieInfo.class);
    //过滤并把每部电影合作的每个演员,都转为包含电影信息1行csv数据
    if(m.getActor().indexOf(actor)!=-1){
        //找到我的演员的电影,接下来把对象转换为csv,代码略。
        ...
        }
    }
    
  • 在转换为 CSV 格式的时候,为了方便我们后续分析,可以考虑转换1行 JSON 为多行的 CSV 数据,这样在统计演员合作次数的时候会更容易统计。例如以下 JSON 数据,可以考虑转换为示例中的 CSV 格式。
    {"_id":{"$oid":"5ad930de6afaf81ac48844a0"},"title":"重庆森林 重慶森林","year":"1994","type":"剧情,爱情","star":8.7,"director":"王家卫","actor":"林青霞,金城武,梁朝伟,王菲,周嘉玲","pp":358053,"time":102,"film_page":"https://movie.douban.com/subject/1291999/"}
    
  • 转换以后,只需要包含film_page、title、actor、star 这几列。这时候统计演员的合作次数只需要统计每个演员出现的次数就可以了。
    https://movie.douban.com/subject/1291999/,重庆森林 重慶森林,林青霞,8.7
    https://movie.douban.com/subject/1291999/,重庆森林 重慶森林,金城武,8.7
    https://movie.douban.com/subject/1291999/,重庆森林 重慶森林,梁朝伟,8.7
    https://movie.douban.com/subject/1291999/,重庆森林 重慶森林,王菲,8.7
    https://movie.douban.com/subject/1291999/,重庆森林 重慶森林,周嘉玲,8.7
    
    import com.alibaba.fastjson.JSON;
    
    import java.io.*;
    
    public class Json2CoActorCsv {
        //演员姓名
        private final static String ACTOR="演员名字";
        private final static String RESOURCE_DIR= new File(Json2CoActorCsv.class.getClassLoader().getResource("Film.json").getPath()).getParent();
    
        public static void main(String[] args) throws IOException {
            //获取Film.json的路径
            String filmJsonPath= Json2CoActorCsv.class.getClassLoader().getResource("Film.json").getPath();
            //读取Film.json
            BufferedReader br=new BufferedReader(new FileReader(filmJsonPath));
            //写到哪个文件
            FileWriter sw=new FileWriter(new File(RESOURCE_DIR,"film.csv"));
            //MovieInfo 类可以参考实验1
            MovieInfo m=null;
            String line;
            while((line=br.readLine())!=null){
                //Fastjson 把每行的json 字符串转换为对象。
                m= JSON.parseObject(line,MovieInfo.class);
                //过滤并把每部电影合作的每个演员,都转为包含电影信息1行csv数据
                if(m.getActor().indexOf(ACTOR)!=-1){
                    //Film_page 作为电影ID
                    String mid=m.getFilm_page();
                    //取出演员的列表
                    String[] actors=m.getActor().split(",");
                    for(String ac:actors){
                        //把电影数据写入csv文件。csv 表头为 ID,电影名称,评分,演员
                        sw.append(mid+","+m.getTitle()+","+ac+","+m.getStar()+","+m.getYear()+"\n");
                    }
                }
            }
            sw.close();
            br.close();
        }
    }
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class MovieInfo  {
    
    	private String title;
    	private int year;
    	private String type;
    	private float star;
    	private String director;
    	private String actor;
    	private String time;
    	private String film_page;
    	private String doubanId;
    	public Set<String> getActorSet(){
    		Set<String> set=new HashSet<>();
    		if(actor!=null){
    			String[] as=actor.split(",");
    			String trimActorName=null;
    			for(String a:as){
    				trimActorName=a.trim();
    				if(!"".equals(trimActorName)){
    					set.add(trimActorName);
    				}
    			}
    		}
    		return set;
    	}
    	public String getTitle() {
    		return title;
    	}
    	public void setTitle(String title) {
    		this.title = title;
    	}
    	public int getYear() {
    		return year;
    	}
    	public void setYear(int year) {
    		this.year = year;
    	}
    	public String getType() {
    		return type;
    	}
    	public void setType(String type) {
    		this.type = type;
    	}
    	public float getStar() {
    		return star;
    	}
    	public void setStar(float star) {
    		this.star = star;
    	}
    	public String getDirector() {
    		return director;
    	}
    	public void setDirector(String director) {
    		this.director = director;
    	}
    	public String getActor() {
    		return actor;
    	}
    	public void setActor(String actor) {
    		this.actor = actor;
    	}
    	public String getFilm_page() {
    		return film_page;
    	}
    	public void setFilm_page(String film_page) {
    		this.film_page = film_page;
    	}
    	public String getTime() {
    		return time;
    	}
    	public void setTime(String time) {
    		this.time = time;
    	}
    	
    	public String getDoubanId() {
    		if(film_page!=null){
    			doubanId=film_page.substring(33,film_page.length()-1);
    		}
    		return doubanId;
    	}
    	
    	@Override
    	public String toString(){
    		return title+"("+year+"),"+"评分:"+star;
    	}
    }
    

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值