面试官嫌我Sql写的太low?要求我重写还加了三个需求?——二战Spark电影评分数据分析_每个类型评分前10的电影 spark

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE genres_average_rating (

id int(11) NOT NULL AUTO_INCREMENT COMMENT ‘自增id’,

genres varchar(100) NOT NULL COMMENT ‘电影类别’,

avgRating decimal(10,2) NOT NULL COMMENT ‘电影类别平均评分’,

update_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT ‘更新时间’,

PRIMARY KEY (id),

UNIQUE KEY genres_UNIQUE (genres)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE ten_most_rated_films (

id int(11) NOT NULL AUTO_INCREMENT COMMENT ‘自增id’,

movieId int(11) NOT NULL COMMENT ‘电影Id’,

title varchar(100) NOT NULL COMMENT ‘电影名称’,

ratingCnt int(11) NOT NULL COMMENT ‘电影被评分的次数’,

update_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT ‘更新时间’,

PRIMARY KEY (id)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


### 项目结构一览图


![在这里插入图片描述](https://img-blog.csdnimg.cn/20210609150051209.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW55dTEyMA==,size_16,color_FFFFFF,t_70)


### 由题意可知


先创建实体类,字段是从建表语句中得来的。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210609150744730.jpg)  
 Entry.scala



package cn.movies.Packet

/**
* @author ChinaManor
* #Description Entry
* #Date: 6/6/2021 17:23
*/
object Entry {
case class Movies(
movieId: String, // 电影的id
title: String, // 电影的标题
genres: String // 电影类别
)
case class Ratings(
userId: String, // 用户的id
movieId: String, // 电影的id
rating: String, // 用户评分
timestamp: String // 时间戳
)
// 需求1MySQL结果表
case class tenGreatestMoviesByAverageRating(
movieId: String, // 电影的id
ratingNum:String,
title: String, // 电影的标题
avgRating: String // 电影平均评分
)
// 需求2MySQL结果表
case class topGenresByAverageRating(
genres: String, //电影类别
avgRating: String // 平均评分
)
// 需求3MySQL结果表
case class tenMostRatedFilms(
movieId: String, // 电影的id
title: String, // 电影的标题
ratingCnt: String // 电影被评分的次数
)
}


再创建个表结构~~![在这里插入图片描述](https://img-blog.csdnimg.cn/202106091509408.gif)  
 Schema.scala



package cn.movies.Packet

import org.apache.spark.sql.types.{DataTypes, StructType}

/**
* @author ChinaManor
* #Description Schema
* #Date: 6/6/2021 17:34
*/
object Schema {
class SchemaLoader {

// movies数据集schema信息

private val movieSchema = new StructType()
  .add("movieId", DataTypes.StringType, false)
  .add("title", DataTypes.StringType, false)
  .add("genres", DataTypes.StringType, false)
// ratings数据集schema信息

private val ratingSchema = new StructType()

  .add("userId", DataTypes.StringType, false)
  .add("movieId", DataTypes.StringType, false)
  .add("rating", DataTypes.StringType, false)
  .add("timestamp", DataTypes.StringType, false)

def getMovieSchema: StructType = movieSchema
def getRatingSchema: StructType = ratingSchema

}
}


然后开始写Main方法,其实只有区区八十行代码。。。


spark总要有实例对象吧。



// 创建spark session
val spark = SparkSession
.builder
.appName(this.getClass.getSimpleName.stripSuffix(“$”))
.master(“local[4]”)
.getOrCreate


然后 new个schema信息



val schemaLoader = new SchemaLoader


然后尝试读取csv文件,  
 // 读取Movie数据集  
 val movieDF: DataFrame = readCsvIntoDataSet(spark, MOVIES\_CSV\_FILE\_PATH, schemaLoader.getMovieSchema)  
 // 读取Rating数据集  
 val ratingDF: DataFrame = readCsvIntoDataSet(spark, RATINGS\_CSV\_FILE\_PATH, schemaLoader.getRatingSchema)


发现读取方法和路径都没有,于是补救一下



// 文件路径
private val MOVIES_CSV_FILE_PATH = “D:\Users\Administrator\Desktop\exam0601\datas\movies.csv”
private val RATINGS_CSV_FILE_PATH = “D:\Users\Administrator\Desktop\exam0601\datas\ratings.csv”

/**

* 读取数据文件,转成DataFrame
*
* @param spark
* @param path
* @param schema
* @return
*/

def readCsvIntoDataSet(spark: SparkSession, path: String, schema: StructType) = {
val dataDF: DataFrame = spark.read
.format(“csv”)
.option(“header”, “true”)
.schema(schema)
.load(path)
dataDF
}


紧接着重头戏来了。。  
 写sql语句,在大数据行业懂得写sql就等于会了80%  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210609153733800.png)



WITH ratings_filter_cnt AS (
SELECT
movieId,
count( * ) AS rating_cnt,
Round(avg( rating ),2) AS avg_rating
FROM
ratings
GROUP BY
movieId
HAVING
count( * ) >= 50
),
ratings_filter_score AS (
SELECT
movieId, – 电影id
rating_cnt, – 个数
avg_rating – 电影平均评分
FROM ratings_filter_cnt
ORDER BY avg_rating DESC – 平均评分降序排序
LIMIT 10 – 平均分较高的前十部电影
)
SELECT
m.movieId,
r.rating_cnt AS ratingNum,
m.title,
r.avg_rating AS avgRating
FROM
ratings_filter_score r
JOIN movies m ON m.movieId = r.movieId ORDER BY r.avg_rating DESC


关键点在于  
 **WITH XXX AS SELECT**  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210609153757308.gif)


最后保存写入mysql表中



def saveToMysql(reportDF: DataFrame) = {
// TODO: 使用SparkSQL提供内置Jdbc数据源保存数据
reportDF
.coalesce(1)
.write
// 追加模式,将数据追加到MySQL表中,再次运行,主键存在,报错异常
.mode(SaveMode.Append)
// 覆盖模式,无需测试,直接将以前数据全部删除,再次重新重建表,肯定不行
//.mode(SaveMode.Overwrite)

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

g-zK5keIiU-1715153681274)]
[外链图片转存中…(img-LNN552FS-1715153681274)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值