用户画像第四章(企业级360°用户画像_标签开发_统计型标签_年龄段标签开发)

统计型标签
统计型标签是需要使用聚合函数计算后得到的标签,比如最近3个月的退单率,用户最常用的支付方式等等.
年龄段标签开发:
1、创建sparkSQL实例没用于读取hbase mysql数据
2、链接mysql数据库
url: String, table: String, properties: Properties
3、读取四级标签数据

inType=HBase##zkHosts=192.168.10.20##zkPort=2181##hbaseTable=tbl_users##family=detail##selectFields=id,birthday

使用## 切分再使用=切分
用户画像第四章(企业级360°用户画像_标签开发_统计型标签_年龄段标签开发)_第1张图片
将map 转换成样HBaseMeta例类
var hbaseMeta: HBaseMeta = getHBaseMeta(fourMap)
4读取mysql数据库中的的五级标签
封装成 TagRule样例类
获取id 和 rule
封装样列类
5根据mysql数据中的四级标签的规则 读取hbase 数据
若使用mysql客户端读取数据效率较慢,将hbase 作为数据源,读取效率较快。
在这里插入图片描述
6、使用五级标签与hbase数据进行匹配获得标签
根据五级标签数据和hbase数据进行标签匹配 的到最终的标签
编写udf函数 。
用户画像第四章(企业级360°用户画像_标签开发_统计型标签_年龄段标签开发)_第2张图片
7、解决数据覆盖的问题【职业标签会覆盖前面的所有标签】
读取test,追加标签后覆盖写入
读取test内的历史标签数据,追加新计算出来的标签到历史数据,最后覆盖写入hbase
A 读取test内的历史标签数据【不是职业标签,是其他的,已经计算出来的标签】
B 追加新计算出来的标签到历史数据
新表join新表,条件是两个表的userId相等
用户画像第四章(企业级360°用户画像_标签开发_统计型标签_年龄段标签开发)_第3张图片
C 最后覆盖写入hbase
8、将最终数据写入hbase

代码:

package cn.itcast.czxy.BD18.Job

import java.util.Properties
import cn.itcast.czxy.BD18.Job.bean.{HBaseMeta, TagRule}
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}

object birthdayTag {
  def main(args: Array[String]): Unit = {
    //1、创建sparkSQL实例没用于读取hbase    mysql数据
    val spark: SparkSession = SparkSession.builder().appName("birthdayTag").master("local[*]").getOrCreate()

    //2、链接mysql数据库
    //url: String, table: String, properties: Properties
    var url="jdbc:mysql://bd001:3306/tags_new?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&user=root&password=123456"
    var table="tbl_basic_tag"
    var properties=new Properties
    val mysqlConn: DataFrame = spark.read.jdbc(url,table,properties)

    //隐式转换
    import spark.implicits._
    import scala.collection.JavaConverters._
    import org.apache.spark.sql.functions._
    //3、读取四级标签数据
    //inType=HBase##zkHosts=192.168.10.20##zkPort=2181##hbaseTable=tbl_users##family=detail##selectFields=id,birthday
    val fourDS: Dataset[Row] = mysqlConn.select("rule").where("id=111")

    val fourMap: Map[String, String] = fourDS.map(row => {
      //使用##  切分再使用=切分
      row.getAs("rule").toString.split("##") //zkHosts=192.168.10.20      zkPort=2181
        .map(kv => {
        //zkHosts=192.168.10.20
        //zkPort=2181
        val arr: Array[String] = kv.split("=") // zkHosts    192.168.10.20,zkPort    2181
        (arr(0), arr(1))
      })
    }).collectAsList().get(0).toMap

    //将map 转换成样HBaseMeta例类
    var hbaseMeta:HBaseMeta=getHBaseMeta(fourMap)

    //println(hbaseMeta.selectFields)


    //4、读取五级标签数据
    val fiveDS: Dataset[Row] = mysqlConn.select("id","rule").where("pid=111")
    //封装成 TagRule样例类

    val fiveTagRule: DataFrame = fiveDS.map(row => {
      //获取数据
      val id: Int = row.getAs("id").toString.toInt
      val rule: String = row.getAs("rule").toString

      val arr: Array[String] = rule.split("-")
      var start=""
      var end=""
      if(arr!=null&&arr.length==2){
        start=arr(0)
        end=arr(1)
      }
      (id, start,end)
    }).toDF("tagId", "start", "ent")
    //5、读取hbase数据
    val HBaseDatas: DataFrame = spark.read.format("cn.itcast.czxy.BD18.Job.tools.HBaseDataSource")
      .option(HBaseMeta.ZKHOSTS, hbaseMeta.zkHosts)
      .option(HBaseMeta.ZKPORT, hbaseMeta.zkPort)
      .option(HBaseMeta.HBASETABLE, hbaseMeta.hbaseTable)
      .option(HBaseMeta.FAMILY, hbaseMeta.family)
      .option(HBaseMeta.SELECTFIELDS, hbaseMeta.selectFields)
      .load()

    val hbaseUserDatas: DataFrame = HBaseDatas.select('id.as("id"), regexp_replace('birthday, "-", "").as("birthday"))
    hbaseUserDatas.show()




    //6、使用五级标签与hbase数据进行匹配获得标签

    val joinDatas: Dataset[Row] = hbaseUserDatas.join(fiveTagRule)
      .where(
        hbaseUserDatas.col("birthday")
          .between(fiveTagRule.col("start"), fiveTagRule.col("ent"))
      )
    //joinDatas.show()
    val ageTags: DataFrame = joinDatas.select('id.as("userId"),'tagId.as("tagsId"))




    var getAllTagas=udf((oldTagsId:String,newTagsId:String)=>{
      if (oldTagsId==""){
        newTagsId
      }else if (newTagsId==""){
        oldTagsId
      }else if(oldTagsId==""&& newTagsId==""){
        ""
      }else{
        //拼接历史数据和新数据(可能有重复的数据)
        val alltags   = oldTagsId+","+newTagsId   //83,94,94
        //对重复数据区中去重
        alltags.split(",").distinct//83  94
          //使用逗号分隔,返回字符串类型。
          .mkString(",")//83,94
      }
    })



    //7、解决数据覆盖的问题【职业标签会覆盖前面的所有标签】
    //   读取test,追加标签后覆盖写入
    // 读取test内的历史标签数据,追加新计算出来的标签到历史数据,最后覆盖写入hbase
    //A    读取test内的历史标签数据【不是职业标签,是其他的,已经计算出来的标签】
    val oldTags: DataFrame = spark.read.format("cn.itcast.czxy.BD18.Job.tools.HBaseDataSource")
      .option(HBaseMeta.ZKHOSTS, hbaseMeta.zkHosts)
      .option(HBaseMeta.ZKPORT, hbaseMeta.zkPort)
      .option(HBaseMeta.HBASETABLE,"test")
      .option(HBaseMeta.FAMILY, "detail")
      .option(HBaseMeta.SELECTFIELDS, "userId,tagsId")
      .load()

    //B    追加新计算出来的标签到历史数据
    //新表join新表,条件是两个表的userId相等
    val joinTagas: DataFrame = oldTags.join(ageTags,    oldTags("userId")===ageTags("userId"))

    val allTags: DataFrame = joinTagas.select(
      //处理第一个字段    两个表中的多个userId字段,只读取一个
      when((oldTags.col("userId").isNotNull),(oldTags.col("userId")))
        .when((ageTags.col("userId").isNotNull),(ageTags.col("userId")))
        .as("userId"),

      //处理第二个字段  将两个字段个合并一起
      //自定义函数用于做数据的凭借
      getAllTagas(oldTags.col("tagsId"),ageTags.col("tagsId")).as("tagsId")
    )
    //allTags.show()
    //C    最后覆盖写入hbase
    //8、将最终数据写入hbase
    allTags.write.format("cn.itcast.czxy.BD18.Job.tools.HBaseDataSource")
      .option("zkHosts", hbaseMeta.zkHosts)
      //HBaseMeta.ZKPORT=>"zkPort"
      //hbaseMeta.zkPort=>2181
      .option(HBaseMeta.ZKPORT, hbaseMeta.zkPort)
      .option(HBaseMeta.HBASETABLE,"test")
      .option(HBaseMeta.FAMILY, "detail")
      .option(HBaseMeta.SELECTFIELDS, "userId,tagsId")
      .save()
  }

  // //将map 转换成样HBaseMeta例类
  def getHBaseMeta(fourMap: Map[String, String]): HBaseMeta = {
    HBaseMeta(fourMap.getOrElse(HBaseMeta.INTYPE,""),
      fourMap.getOrElse(HBaseMeta.ZKHOSTS,""),
      fourMap.getOrElse(HBaseMeta.ZKPORT,""),
      fourMap.getOrElse(HBaseMeta.HBASETABLE,""),
      fourMap.getOrElse(HBaseMeta.FAMILY,""),
      fourMap.getOrElse(HBaseMeta.SELECTFIELDS,""),
      fourMap.getOrElse(HBaseMeta.ROWKEY,"")
    )
  }

}

你可能感兴趣的:(用户画像)