天津,10
天津,11
天津,13
天津,14
北京,13
北京,16
北京,17
北京,18
上海,15
上海,11
上海,15
上海,17
重庆,14
重庆,12
重庆,13
重庆,14
这个案例也许并不是那么恰当,其实,也可以利用到邮件切分等场景,这里算是抛砖引玉把。
聚合函数(AggregateFunction)
关于聚合函数,官方文档上的这张图,就充分的解释了其工作原理,主要计算通过
-
createAccumulator()
-
accumulate()
-
getValue()
这几个方法来完成,首先我们createAccumulator创建累加器,然后调用accumulate累加计算,最后getValue获取值。
当然这只是完成了初步工作,
-
retract()
-
merge()
-
resetAccumulator()
我们还需要回滚,合并,重置累加器等操作以适应不同的计算场景。
好了,我们的案例,再次来到了大家喜闻乐见的意甲联赛,这次我们统计俱乐部的进球数,还是使用了一个更靠谱的规则,就是给客场进球加了一个权重,然后来计算加权场均进球数。
先来创建累加器
class WeightedAvgAccum {
var sum = 0
var count = 0
}
然后创建计算函数
import java.lang.{Integer => JInteger,String => JString}
import org.apache.flink.table.functions._
class WeightedAvg(iWeight:Int) extends AggregateFunction[JInteger, WeightedAvgAccum] {
override def createAccumulator(): WeightedAvgAccum = {
new WeightedAvgAccum
}
override def getValue(acc: WeightedAvgAccum): JInteger = {
if (acc.count == 0) {
null
} else {
acc.sum / acc.count
}
}
def accumulate(acc: WeightedAvgAccum,club:JString, home: JInteger, visit: JInteger): Unit = {
acc.sum += home + visit * iWeight
acc.count += 1
}
def resetAccumulator(acc: WeightedAvgAccum): Unit = {
acc.count = 0
acc.sum = 0
}
}
接下来,我们来测试一下:
import org.apache.flink.api.scala.typeutils.Types
import org.apache.flink.api.scala.{DataSet, ExecutionEnvironment}
import org.apache.flink.table.api.TableEnvironment
import org.apache.flink.table.sources.CsvTableSource
import org.apache.flink.types.Row
import org.apache.flink.api.scala._
object Testf {
def main(args: Array[String]): Unit = {
val filePath = “E:\\devlop\\workspace\\streaming1\\src\\main\\resources\\testdata.csv”
val env = ExecutionEnvironment.getExecutionEnvironment
val tableEnv = TableEnvironment.getTableEnvironment(env)
val csvtable = CsvTableSource
.builder
.path(filePath)
.ignoreFirstLine
.fieldDelimiter(“,”)
.field(“rank”, Types.INT)
.field(“player”, Types.STRING)
.field(“club”, Types.STRING)
.field(“matches”, Types.INT)
.field(“red_card”, Types.INT)
.field(“total_score”, Types.INT)
.field(“total_score_home”, Types.INT)
.field(“total_score_visit”, Types.INT)
.field(“pass”, Types.INT)
.field(“shot”, Types.INT)
.build
tableEnv.registerTableSource(“test”, csvtable)
tableEnv.registerFunction(“myf”,new MyFunction(“111”))
tableEnv.registerFunction(“wag”,new WeightedAvg(2))
val tableTest3 = tableEnv.sqlQuery(“select club,wag(club,total_score_home,total_score_visit) as ag from test group by club”)
tableEnv.toDataSet[Row](tableTest3).print()
}
}
查看下结果:
切沃,2
拉齐奥,3
斯帕尔,1
博洛尼亚,1
国际米兰,3
帕尔马,2
恩波利,2
桑普多利亚,4
那不勒斯,4
都灵,2
AC米兰,3
亚特兰大,5
佛罗伦萨,2
卡利亚里,2
罗马,3
乌迪内斯,2
弗罗西诺内,2
尤文图斯,4
热那亚,3
萨索洛,2
最后(敲黑板),大家在聚合表的案例里,应该发现我使用了Java的基础类型,而不是Scala的数据类型,这是因为在UDF执行过程中,数据的创建,转换以及装箱拆箱都会带来额外的消耗,所以 Flink 官方,其实推荐UDF进来使用Java编写。
UDF其实是一个很神奇的东西,值得我们去探索与研究,下一期写点什么呢?如果您有建议或意见,欢迎与我联系,探讨。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
那么如何才能正确的掌握Redis呢?
为了让大家能够在Redis上能够加深,所以这次给大家准备了一些Redis的学习资料,还有一些大厂的面试题,包括以下这些面试题
-
并发编程面试题汇总
-
JVM面试题汇总
-
Netty常被问到的那些面试题汇总
-
Tomcat面试题整理汇总
-
Mysql面试题汇总
-
Spring源码深度解析
-
Mybatis常见面试题汇总
-
Nginx那些面试题汇总
-
Zookeeper面试题汇总
-
RabbitMQ常见面试题汇总
JVM常频面试:
Mysql面试题汇总(一)
Mysql面试题汇总(二)
Redis常见面试题汇总(300+题)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
汇总
-
Spring源码深度解析
-
Mybatis常见面试题汇总
-
Nginx那些面试题汇总
-
Zookeeper面试题汇总
-
RabbitMQ常见面试题汇总
JVM常频面试:
[外链图片转存中…(img-8pJXwF7Q-1712774851509)]
Mysql面试题汇总(一)
[外链图片转存中…(img-oda4vsuu-1712774851509)]
Mysql面试题汇总(二)
[外链图片转存中…(img-YCgMpmOR-1712774851509)]
Redis常见面试题汇总(300+题)
[外链图片转存中…(img-E2ND6IQC-1712774851510)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-ieUnnlgv-1712774851510)]