Table of Contents
我们将DataFrame看作是由一行行(Row)的记录组成的。有时我们会比较两个有相同Schema的DataFrame,而获取一个DataFrame相对于另一DataFrame需要增/删/改的记录。也就是说,原始有一个老DataFrame,在经过这些增/删/改的操作后,就能得到参与比较的新DataFrame。当然,在决定改的记录时,一定是规定了这两个DataFrame相同的主键字段。下面分享自己求取这些子DataFrame的方法。
两个DataFrame的纯比较
这里给出这两个DataFrame的例子,和它们的主键:
val oldDF = Seq[(Integer,String,Integer)](
(1, "zhang", 12),
(2, "wang", 49),
(3, "li", 18),
(4, "luo", 28)
).toDF("Id", "Name", "Age")
val newDF = Seq[(Integer,String,Integer)](
(2, "wang", 49),
(3, "li", 61),
(4, "luo", 28),
(5, "zhou", 58)
).toDF("Id", "Name", "Age")
val priKeys = Seq("Id")
一般来说,比较两个DataFrame得到的增/删/改三个子DataFrame可看作一组结果。而有时会不区分增加和更改记录,这是因为:1)计算更简单;2)有些数据库的Update操作就可以涵盖Insert,例如,DB2就有MERGE的语句统一处理这两种记录。这里将它们称作删除/增改两个子DataFrame。下面是实现的Spark代码:
import org.apache.spark.sql.DataFrame
case class GroupInsUptDel(insDF: DataFrame, uptDF: DataFrame, delDF: DataFrame)
def genInsUptDel(newDF: DataFrame, oldDF: DataFrame, priKeys: Seq[String]): GroupInsUptDel = {
val oldCL = oldDF.columns
val delDF = oldDF.join(newDF, priKeys, "left_anti")
val insDF = newDF.join(oldDF, priKeys, "left_anti")
val uptDF = newDF.join(oldDF, priKeys, "left_semi").select(oldCL.head, oldCL.tail:_*).exceptAll(oldDF)
GroupInsUptDel(insDF, uptDF, delDF)
}
case class GroupDeltUpsr(deltDF: DataFrame, upsrDF: DataFrame)
def genDeltUpsr(newDF: DataFrame, oldDF: DataFrame, priKeys: Seq[String]): GroupDeltUpsr = {
val oldCL = oldDF.columns
val deltDF = oldDF.join(newDF, priKeys, "left_anti")
val upsrDF = newDF.select(oldCL.head, oldCL.tail:_*).exceptAll(oldDF)
GroupDeltUpsr(deltDF, upsrDF)
}
求取增/删/改三个子DataFrame的例子:
scala> val grpOne = genInsUptDel(newDF, oldDF, priKeys)
grpOne: GroupInsUptDel = GroupInsUptDel([Id: int, Name: string ... 1 more field],[Id: int, Name: string ... 1 more field],[Id: int, Name: string ... 1 more field])
scala> grpOne.insDF.show(false)
+---+----+---+
|Id |Name|Age|
+---+----+---+
|5 |zhou|58 |
+---+----+---+

本文探讨如何在Spark中比较两个具有相同Schema的DataFrame,以获取增、删、改记录。通过实例展示了考虑时间戳和处理null值的情况,提供了解决这些问题的Spark代码实现。
最低0.47元/天 解锁文章
5206

被折叠的 条评论
为什么被折叠?



