数据分析
本项目的数据是采集电商网站的用户行为数据,主要包含用户的4种行为:搜索、点击、下单和支付。
(1)数据采用_分割字段
(2)每一行表示用户的一个行为,所以每一行只能是四种行为中的一种。
(3)如果搜索关键字是null,表示这次不是搜索
(4)如果点击的品类id和产品id是-1表示这次不是点击
(5)下单行为来说一次可以下单多个产品,所以品类id和产品id都是多个,id之间使用逗号,分割。如果本次不是下单行为,则他们相关数据用null来表示
(6)支付行为和下单行为类似
字段说明
编号 字段名称 字段类型 字段含义
1 date String 用户点击行为的日期
2 user_id Long 用户的ID
3 session_id String Session的ID
4 page_id Long 某个页面的ID
5 action_time String 动作的时间点
6 search_keyword String 用户搜索的关键词
7 click_category_id Long 某一个商品品类的ID
8 click_product_id Long 某一个商品的ID
9 order_category_ids String 一次订单中所有品类的ID集合
10 order_product_ids String 一次订单中所有商品的ID集合
11 pay_category_ids String 一次支付中所有品类的ID集合
12 pay_product_ids String 一次支付中所有商品的ID集合
13 city_id Long 城市 id
需求一:Top10热门品类
品类是指产品的分类,大型电商网站品类分多级,咱们的项目中品类只有一级,不同的公司可能对热门的定义不一样。我们按照每个品类的点击、下单、支付的量来统计热门品类。
鞋 点击数 下单数 支付数
衣服 点击数 下单数 支付数
生活用品 点击数 下单数 支付数
例如,综合排名=点击数20%+下单数30%+支付数*50%
本项目需求优化为:先按照点击数排名,靠前的就排名高;如果点击数相同,再比较下单数;下单数再相同,就比较支付数。
需求分析
代码实现
package com.atguigu.req
import org.apache.spark.rdd.RDD
import org.apache.spark.{
SparkConf, SparkContext}
import scala.collection.mutable.ListBuffer
object TopN {
def main(args: Array[String]): Unit = {
//1.创建SparkConf并设置App名称
val conf: SparkConf = new SparkConf().setAppName("SparkCoreTest").setMaster("local[*]")
//2.创建SparkContext,该对象是提交Spark App的入口
val sc: SparkContext = new SparkContext(conf)
// 读取数据
val rdd: RDD[String] = sc.textFile("D:\\MyWork\\WorkSpaceIDEA\\scalaDemo\\spark\\input\\user_visit_action.txt")
// 对读取的数据进行转换,封装为UserVisitAction,放到RDD中
val actionRDD: RDD[UserVisitAction] = rdd.map {
line => {
// 对读取的每一行数据进行切分
val fields: Array[String] = line.split("_")
// 封装程UserVisitAction对象
UserVisitAction(
fields(0),
fields(1).toLong,
fields(2),
fields(3).toLong,
fields(4),
fields(5),
fields(6).toLong,
fields(7).toLong,
fields(8),
fields(9),
fields(10),
fields(11),
fields(12).toLong
)
}
}
// 对数据进行处理:对每一条用户行为进行处理,转换为一个CategoryCountInfo对象
val infoRDD: RDD[CategoryCountInfo] = actionRDD.flatMap {
userAction => {
// 判断是否为点击
if (userAction.click_category_id != -1) {
List(CategoryCountInfo(userAction.click_category_id.toString, 1, 0, 0))
} else if (userAction.order_category_ids != "null") {
// 判断是否为下单
// 对下单的品类ID就行切分
val ids: Array[String] = userAction.order_category_ids.split(",")
val list_order: ListBuffer[CategoryCountInfo] = ListBuffer[CategoryCountInfo]()
for (elem <- ids) {
list_order.append(CategoryCountInfo(elem, 0, 1, 0))
}
list_order
} else if (userAction.pay_category_ids != "null") {
// 判断是否为支付
// 对下单的品类ID就行切分
val ids: Array[String] = userAction.pay_category_ids.split(",")
val list_pay: ListBuffer[CategoryCountInfo] = ListBuffer[CategoryCountInfo]()
for (elem <- ids) {
list_pay.append(CategoryCountInfo(elem, 0, 1, 0))
}
list_pay
} else {
// 其它
Nil
}