开发者学堂课程【2020版大数据实战项目之 DMP 广告系统(第五阶段):报表统计_数据的区域分布_代码开发】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/680/detail/11815
报表统计_数据的区域分布_代码开发
内容介绍:
一、按照省市进行分组求得结果
二、落地到 report 表中
一、按照省市进行分组求得结果
1、本课程继续完成数据集在地区上的区域上的分布情况报表的数据生成。还有两步需要完成,第一步是按照省市进行分组求得结果,第二部落地到 report 表中。先进行第一步,按照省市进行分组求得结果,首先 source 是 option 类型,这样的话应该 val sourceDF = source.get,让 source.get 获取其中的内容,转为 data frame。可以直接使用 get,而不使用 getorelse。因为前面已经判断它为空了,如果为空下面这行代码 val sourceDF = source.get,根本不会执行,只要走到这行代码,source 是一定有值的。拿到 sourceDF 之后可以进行 groupby(),by 的时候要注意一件事情,按照两列进行 by,第一列叫做 region,第二列叫做 city。如果想用点这种形式来进行相应的处理操作的时候,就必须导入 spark.implicits._,把所有的隐式转换导入,这个时候就可以使用 .region 生成 column,.city 生成一个 city column。除了这种方法以外,也可以使用 $,$ 后面加上字符串的标志,也可以生产一个 column 对象,两种方式是等价的,使用哪一种都行。这里暂且先采用 $ 的形式,前面在 spark 的时候就用的 $ 的形式。 这种形式在很多开源代码里很常见,所以选择 $ 这种形式。
2、按照 region 和 city 分组以后,就可以直接求 count,求 count 以后就可以把分组统计的结果求出来。count 生成的那一列,不知道叫什么名字,所以推荐大家使用 agg,使用 agg 的时候可以导入一个方式 import_org.apache.spark.sql.functions._ ,使用 count 的方式直接 as count,这样相对容易一些。count 要求传一个东西,如果没有可以选择 *。再写一个 select 保证结果是没有问题的,select 三列,第一列是 region,第二列 city,第三列是 count,然后就生成了一个结果。“.”和“$ ”的写法完全等价,没有任何区别,过程上会有区别,原理上有区别,但是结果不会有任何区别。然后就可以得到一个表示结果的结果集,得到 result 以后就可以落地到 Kudo 表中了。但还是先进行 show 查看一下,再保存到 kudo 之前,show 一下是非常好的习惯,检查数据没问题,再往 Kudo 表当中保存。
//1.创建SparkSession
val spark=SparkSession. builder()
.appName(name="report data region")
. master(master="1oca1[6]")
.loadConfig()
.getOrCreate()
import spark. implicits. _
import_org.apache.spark.sql.functions._
//2.读取ODS层数据
val source:Option[DataFrame]=spark.readKuduTable(SOURCE_ TABLE_NAME)
if(source.isEmpty) return
val sourceDF = source. Get
//3.按照省市进行分组求得结果
val result =sourceDF.groupBy( cols=$"region",$"city").
. agg(count( columnName= "*") as "count")
. select(cos='region,'city,'count)
3、结果已经获取到了,一个是 region,一个是 city,一个是 count。
这个数据集其实并不是特别大,接下来就可以把这个表落地到 report 表当中。
二、落地到 report 表中
1、先使用 spark.creatKudoTable,creatKudoTable 的时候要求给三条数据,第一个是 tablename,已经有了,是 TARGET_TABLE_NAME,第二个是 schema,把 schema 创建出来,第三个是 keys。
2、select 代表了最终 result 的三个列,分别是 region、city、count,按照哪些列进行分区呢?哪些列应该作为主件呢?这三列当中哪些列作为主件?region 和 city 作为主件,这样的话 keys 给一个 list,List分别对应 region 和 city。拿到 keys 以后去创建 scheme,new schema,new schema 是 Kudo 的 schema,在这个 schema 当中要创建一个 list,list 当中放具体的 column builder,new Columnbuilder 是 ColumnSchemaBuilder。第一个要传入的内容是列的名字,所以是 region,region 以后,第二项数据要给的是一个数据类型.
type 是 kudo 的 type。region 是 string 类型的,不可以为空,因为主件都不可以为空。还有一点它是否是主件,是否是 key?很明显是,只有主件才可以作为分区的件。build 获取到结果,再来一条,只需要把 region 改为 city 即可。再来一条把 city 改为 count,把 STRING 改为 INT64,也有可能是 INT32。
3、如果一会儿报错,修改一下 INT 就可以了,它不可以为空,也不是主件。这个时候报错了,原因是这是 scala 的 list,schema 接收的是 java 的 util 包下的 list。import scala.collection. JAVAConverters._,在后面加上 asJava,这样就成功的把 scala 的 list转为 JAVA 的 list,并且传入进去。createtable 当中要给三个内容,第一个是 TARGET_TABLE_NAME,第二个是 schema,第三个是 keys,接下来 result.saveToKudo 保存进去。保存进去表名叫 TARGET_TABLE_NAME,这个时候整个内容就已经编写完成了。
//4.落地到 Report表中
spark.createKuduTable(TARGET TABLE NAME, schema, keys)
result.saveToKuduo
}
private val SOURCE_TABLE_NAME=ETLRunner.
ODS_TABLE_NAME
private val TARGET_TABLE_NAME ="report_data_region_ "+KuduHelper. formatted Date()
private val keys=List("region","city")
import scala. collection.JavaConverters. _
private val schema=new Schema(
List(
new ColumnSchemaBuilder(name="region", Type.STRING). nullable(nullable=false). key(key=true). buil
new ColumnSchemBuilder(name= “city” , Type、STRING), nullable(nullable=false). key(key=true), build(
new ColumnSchemaBuilder(name="count", Type.INT64). nullable( nulle=false). key=false). build
) .asJava
)
}
4、梳理一下流程,有四步。第一步,创建 sparksession,第二步,读取数据,第三步,按照省市进行分组并且统计,第四步落地到 report 表当中。开始运行一下,结果没有任何问题,
已经把数据保存到了 Kudo 当中。接下来应该查看一下数据有没有问题,打开 kudo,找到 tables,这多了一个叫做 report_data_region_190709 的表,
点开这个表,大家会发现三列数据没有任何问题,确实是 INT64。
5、接下来就可以把建立 impala 语句的表复制一下,进入到 shell 窗口当中,在 cdh01 当中,impala shell,进入到 impala 当中,use dmp 这个库, use 这个库以后,把 impala 语句复制过来,
CREATE EXTERNAL TABLE ` report_data_region 190709 ` STORED AS KUDU
TBLPROPERTIES(
'kudu. Table_name'='report_data_region_190709',
'kudu. master_ addresses'='cdh01:7051,cdh02;7051,
cdh03:7051')
给定一个分号,创建这张表 select * from report_data_region_190709,然后就可以进行相应的查询了。也可以 order by 一下,order by count,升序还是降序,想看到 Top10的话应该 desc 降序,limit 10取得数据量最多的10个省市。
回车执行一下,
上海的数据是最多的396条,其次是重庆,这样数据就统计完毕了。