Flink_继承TableAggregateFunction实现topN

Flink中的UDF,UDAF,UDTF,以及多进多出
基于TableAPI sql暂时用Rank就可以
package com.atguigu.sqlfunction

import com.atguigu.sourceandsink.SensorReading
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.table.api.Table
import org.apache.flink.table.api.scala._
import org.apache.flink.table.functions.{AggregateFunction, ScalarFunction, TableAggregateFunction, TableFunction}
import org.apache.flink.types.Row
import org.apache.flink.util.Collector

object TableAggregateFunctionTest {
def main(args: Array[String]): Unit = {
val streamEnv: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
streamEnv.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
val tableEnv: StreamTableEnvironment = StreamTableEnvironment.create(streamEnv)//默认blinkplanner
//读取数据
val inputStream: DataStream[String] = streamEnv.readTextFile(“in/sensor.txt”)
val dataStream: DataStream[SensorReading] = inputStream.map(data => {
val strings: Array[String] = data.split(",")
SensorReading(strings(0), strings(1).toLong, strings(2).toDouble)
}).assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractorSensorReading {
override def extractTimestamp(element: SensorReading): Long = element.timestamp * 1000L
})
val sensorTable: Table = tableEnv.fromDataStream(dataStream,'id,'temperature,'timestamp.rowtime as 'ts)
//调用自定义函数 对id进行hash运算
//tableAPI
val top2Temp = new Top2Temp
val resultApiTable: Table = sensorTable
.groupBy('id)
.flatAggregate(top2Temp('temperature) as ('temp,'rank))
.select('id, 'temp,'rank)
//sql实现

resultApiTable.toRetractStream[Row].print("resultApiTable")
streamEnv.execute()

}
}
//自定义表聚合函数 提取每个传感器所有温度值中最高的两个温度 输出(temp,rank)
class Top2Temp extends TableAggregateFunction[(Double,Int),Top2TempAcc] {
override def createAccumulator(): Top2TempAcc = {
new Top2TempAcc
}
//改变状态
def accumulate(acc:Top2TempAcc,temp:Double)={
//判断当前温度是否比当前温度值大
if(temp>acc.highestTemp){
acc.secondHighTemp = acc.highestTemp
acc.highestTemp = temp
}else if(temp > acc.secondHighTemp){
//如果在最高和第二高之间 替换第二高温度
acc.secondHighTemp = temp
}
}
def emitValue(acc:Top2TempAcc,out:Collector[(Double,Int)])={
out.collect(acc.highestTemp,1)
out.collect(acc.secondHighTemp,2)
}
}
//定义一个类用来表示表聚合函数的状态
class Top2TempAcc{
var highestTemp: Double = Double.MinValue
var secondHighTemp: Double = Double.MinValue
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值