浅析:Spark中的UDF、UDAF函数(一)

UDF:User-defined Function,用户自定义函数。一般为单输出类型,这里以scala代码为例:

/**
     * @function 自定义UDF————依照姓名字符长短倒排学生姓名,并统计姓名字符长度
     * @author Dongh.Wang
     *	郑重声明,scala中自定义函数需继承UDF类
     */
   object UDF {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().master("local").appName("UDF").getOrCreate()
    val nameList: List[String] = List[String]("zhangsan", "lisi", "wangwu", "zhaoliu", "tianqi")
    import spark.implicits._
    val nameDF: DataFrame = nameList.toDF("name")
    nameDF.createOrReplaceTempView("students")
    nameDF.show()

    spark.udf.register("STRLEN",(name:String)=>{
      			name.length
   		 })
    spark.sql("select name ,STRLEN(name) as length from students order by length desc").show(100)
   	 }
  }

UDAF:User- Defined Aggregation Funcation,用户定义聚合函数。注意关键词“聚合”,一般为多进单出类型;有使用数据库经验的小伙伴可以思考一下avg、sum、count、max、min这五个颇具代表性的聚合函数。
这里我们依然用scala代码来完成任务。
依然是统计学生(但例子与上面UDF并不相同),UDAF与UDF不同,它必须继承UserDefinedAggregateFunction,并重写以下8个方法:

class MyUDAF extends UserDefinedAggregateFunction  {
  //输入数据的类型
  def inputSchema: StructType = {
    DataTypes.createStructType(Array(DataTypes.createStructField("uuuu", StringType, true)))
  }

  /**
    * 为每个分组的数据执行初始化值
     */
  def initialize(buffer: MutableAggregationBuffer): Unit = {
    buffer(0) = 0
  }
  // 每个组,有新的值进来的时候,进行分组对应的聚合值的计算
  def update(buffer: MutableAggregationBuffer, input: Row): Unit = {
    buffer(0) = buffer.getAs[Int](0)+1
  }
  // 最后merger的时候,在各个节点上的聚合值,要进行merge,也就是合并
  def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
    buffer1(0) = buffer1.getAs[Int](0)+buffer2.getAs[Int](0)
  }
  // 聚合操作时,所处理的数据的类型
  def bufferSchema: StructType = {
    DataTypes.createStructType(Array(DataTypes.createStructField("QQQQ", IntegerType, true)))
  }
  // 最后返回一个最终的聚合值要和dataType的类型一一对应
  def evaluate(buffer: Row): Any = {
    buffer.getAs[Int](0)
  }
  // 最终函数返回值的类型
  def dataType: DataType = {
    DataTypes.IntegerType
  }
  //多次运行 相同的输入总是相同的输出,确保一致性
  def deterministic: Boolean = {
      true
  }
}

UDAF函数的调用:

object UDAF {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().master("local").appName("UDAF").getOrCreate()
    val nameList: List[String] = List[String]("zhangsan", "lisi", "lisi", "lisi", "lisi", "wangwu",
                                                  "zhangsan", "lisi", "zhangsan", "wangwu")
    import spark.implicits._
    val frame: DataFrame = nameList.toDF("name")
    frame.createOrReplaceTempView("students")

    //select  name ,count(*) from table group by name
    /**
      * 注册 UDAF 函数
      */
    spark.udf.register("NAMECOUNT",new MyUDAF())

    spark.sql("select name,NAMECOUNT(name) as count from students group by name").show(100)
  }
}

你可能感兴趣的:(浅析:Spark中的UDF、UDAF函数(一))