idmaping代码实现

object IdMappingGen {

  def main(args: Array[String]): Unit = {
    Logger.getLogger("org").setLevel(Level.WARN)
    val spark = SparkSession.builder().appName("IDMAPPING映射字典生成").master("local[*]").getOrCreate()
    import spark.implicits._
    import org.apache.spark.sql.functions._

    // 加载T日的日志
    val schema = new StructType()
        .add("deviceid",DataTypes.StringType)
        .add("account",DataTypes.StringType)
        .add("timestamp",DataTypes.LongType)
    val t_log = spark.read.option("header",true).schema(schema).csv("dw_etl\\data\\idmp_testdata\\T_day_log")
    t_log.show(100,false)

    // 1. 对当天日志中的访问记录进行账号评分

    // 1.1 过滤掉完全没有账号登录的设备记录
    val ifBlank = (s:String)=>{StringUtils.isBlank(s)}
    spark.udf.register("isBlank",ifBlank)

    // 有登录记录的设备
    val haveAccount = t_log.where("!isBlank(account)")
    t_log.cache()
    haveAccount.show(100,false)

    // 没有账号登录记录的设备
    val noAccount = t_log.groupBy("deviceid").agg(max("account") as "account",min("timestamp") as "ts").where("account is null")

    // 1.2 对同一个设备上的同一个账号,取时间最早的第一条

    val firstRecord = haveAccount.groupBy("deviceid","account").agg(min("timestamp") as "ts")

    firstRecord.show(100,false)

    // 1.3 对每个设备上的每个登录账号评分(越早分越高)
    val window = Window.partitionBy("deviceid").orderBy("ts")
    val scored = firstRecord.select('deviceid,'account,'ts,row_number() over(window) as "rn")
        .selectExpr("deviceid","account","ts","100-(rn-1)*10 as score")

    scored.show(100,false)

    // 1.4 将账号评分结果 union 无账号的数据
    val t_result = scored.union(noAccount.selectExpr("deviceid","account","ts","null"))

    t_result.show(100,false)

    // 2. 加载T-1日的映射字典
    // 2.1 读取数据
    val preIdmp = spark.read.json("dw_etl\\data\\idmp_testdata\\T-1dict_out")
    preIdmp.printSchema()
    preIdmp.show(100,false)
    preIdmp.createTempView("preidmp")
    /**
     * +--------+-----+-----------------------------+
     * |deviceid|guid |uid_list                     |
     * +--------+-----+-----------------------------+
     * |did01   |u01  |[[u01, 100, 1]]              |
     * |did02   |u02  |[[u02, 100, 3], [u03, 90, 8]]|
     * |did03   |did03|[]                           |
     * +--------+-----+-----------------------------+
     */
    // 2.2 格式扁平化
    val preUidScore = spark.sql(
      """
        |
        |select
        |deviceid,
        |uid_score.account as account,
        |uid_score.timestamp as ts,
        |uid_score.score as score
        |
        |from preidmp lateral view explode(uid_list) tmp as uid_score
        |
        |""".stripMargin)

    preUidScore.show(100,false)

    // 2.3 将历史idmp数据中,账号绑定列表为空的数据单独拎出来
    val preNoUid = preIdmp.where("size(uid_list)=0").selectExpr("deviceid","null","null","null")

    // 3.合并T和T-1

    // 3.1 分数聚合
    val wholeDevices = t_result.union(preUidScore).union(preNoUid)
    wholeDevices.show(100,false)
    wholeDevices.createTempView("whole")

    val todayUidScoreResult = spark.sql(
      """
        |select
        |deviceid,
        |account,
        |ts,
        |score
        |from
        |(
        |select
        |
        |deviceid,
        |account,
        |ts,
        |score,
        |row_number() over(partition by deviceid order by account desc) as rn
        |
        |from
        |(
        |select
        |
        |deviceid,
        |account,
        |min(ts) as ts,
        |sum(score) as score
        |
        |from whole
        |group by deviceid,account
        |) o1
        |) o2
        |where !(rn>1 and account is null)
        |
        |""".stripMargin)
        .show(100,false)

    /**
     * +--------+-------+---+-----+
     * |deviceid|account|ts |score|
     * +--------+-------+---+-----+
     * |did04   |null   |16 |null |
     * |did03   |u04    |12 |100  |
     * |did02   |u03    |8  |190  |
     * |did02   |u02    |3  |190  |
     * |did01   |u01    |1  |200  |
     * +--------+-------+---+-----+
     */

    // 3.2 将同一个设备的账号评分整理到一起,选出guid,并转成json格式
    // TODO


    // 保存结果



    spark.close()
  }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程简介:  本项目课程是一门极具综合性和完整性的大型项目课程;课程项目的业务背景源自各类互联网公司对海量用户浏览行为数据和业务数据分析的需求及企业数据管理、数据运营需求。 本课程项目涵盖数据采集与预处理、数据仓库体系建设、用户画像系统建设、数据治理(元数据管理、数据质量管理)、任务调度系统、数据服务层建设、OLAP即席分析系统建设等大量模块,力求原汁原味重现一个完备的企业级大型数据运营系统。  拒绝demo,拒绝宏观抽象,拒绝只讲不练,本课程高度揉和理论与实战,并兼顾各层次的学员,真正从0开始,循序渐进,每一个步骤每一个环节,都会带领学员从需求分析开始,到逻辑设计,最后落实到每一行代码,所有流程都采用企业级解决方案,并手把手带领学员一一实现,拒绝复制粘贴,拒绝demo化的实现。并且会穿插大量的原创图解,来帮助学员理解复杂逻辑,掌握关键流程,熟悉核心架构。   跟随项目课程,历经接近100+小时的时间,从需求分析开始,到数据埋点采集,到预处理程序代码编写,到数仓体系搭建......逐渐展开整个项目的宏大视图,构建起整个项目的摩天大厦。  由于本课程不光讲解项目的实现,还会在实现过程中反复揉和各种技术细节,各种设计思想,各种最佳实践思维,学完本项目并勤于实践的话,学员的收获将远远超越一个项目的具体实现,更能对大型数据系统开发产生深刻体悟,对很多技术的应用将感觉豁然开朗,并带来融会贯通能力的巨大飞跃。当然,最直接的收获是,学完本课程,你将很容易就拿到大数据数仓建设或用户画像建设等岗位的OFFER课程模块: 1. 数据采集:涉及到埋点日志flume采集系统,sqoop业务数据抽取系统等; 2. 数据预处理:涉及到各类字典数据构建,复杂结构数据清洗解析,数据集成,数据修正,以及多渠道数据的用户身份标识打通:ID-MAPPING等;3. 数据仓库:涉及到hive数仓基础设施搭建,数仓分层体系设计,数仓分析主题设计,多维分析实现,ETL任务脚本开发,ETL任务调度,数据生命周期管理等;4. 数据治理:涉及数据资产查询管理,数据质量监控管理,atlas元数据管理系统,atlas数据血缘管理等;5. 用户画像系统:涉及画像标签体系设计,标签体系层级关系设计,各类标签计算实现,兴趣类标签的衰减合并,模型标签的机器学习算法应用及特征提取、模型训练等;6. OLAP即席分析平台:涉及OLAP平台的整体架构设计,技术选型,底层存储实现,Presto查询引擎搭建,数据服务接口开发等;7. 数据服务:涉及数据服务的整体设计理念,架构搭建,各类数据访问需求的restapi开发等;课程所涉及的技术: 整个项目课程中,将涉及到一个大型数据系统中所用到的几乎所有主要技术,具体来说,包含但不限于如下技术组件:l Hadoopl Hivel HBasel SparkCore /SparkSQL/ Spark GRAPHX / Spark Mllibl Sqoopl Azkabanl Flumel lasal Kafkal Zookeeperl Solrl Prestop
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值