Apache spark 使用Spark从多个数据集中查找完整性

Apache spark 使用Spark从多个数据集中查找完整性,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我需要使用Spark 2验证多个数据集(或csv)中存在的某些数据。这可以定义为从所有数据集中再匹配两个密钥,并从所有数据集中生成所有匹配和非匹配密钥的报告。 例如,有四个数据集,每个数据集有两个与其他键匹配的键。这意味着所有数据集都需要在定义的两个匹配键上进行匹配。假设userId和userName是以下数据集中的两个匹配键: Dataset A: userId,userName,age,contactNumber Dataset B: orderId,orderDetails,userId,

我需要使用Spark 2验证多个数据集(或csv)中存在的某些数据。这可以定义为从所有数据集中再匹配两个密钥,并从所有数据集中生成所有匹配和非匹配密钥的报告。
例如,有四个数据集,每个数据集有两个与其他键匹配的键。这意味着所有数据集都需要在定义的两个匹配键上进行匹配。假设userId和userName是以下数据集中的两个匹配键:

Dataset A: userId,userName,age,contactNumber
Dataset B: orderId,orderDetails,userId,userName
Dataset C: departmentId,userId,userName,departmentName
Dataset D: userId,userName,address,pin

Dataset A:    
userId,userName,age,contactNumber
1,James,29,1111
2,Ferry,32,2222
3,Lotus,21,3333

Dataset B:    
orderId,orderDetails,userId,userName
DF23,Chocholate,1,James
DF45,Gifts,3,Lotus

Dataset C:    
departmentId,userId,userName,departmentName
N99,1,James,DE
N100,2,Ferry,AI

Dataset D:    
userId,userName,address,pin
1,James,minland street,cvk-dfg
需要生成报告(或类似报告),如

------------------------------------------
userId,userName,status
------------------------------------------
1,James,MATCH
2,Ferry,MISSING IN B, MISSING IN D
3,Lotus,MISSING IN B, MISSING IN C, MISSING IN D
我已尝试按以下方式加入数据集

DatsetA-B:
userId,userName,age,contactNumber,orderId,orderDetails,userId,userName,status
1,James,29,1111,DF23,Chocholate,1,James,MATCH
2,Ferry,32,2222,,,,,Missing IN Left
3,Lotus,21,3333,DF45,Gifts,3,Lotus,MATCH

DatsetC-D:
departmentId,userId,userName,departmentName,userId,userName,address,pin,status
N99,1,James,DE,1,James,minland street,cvk-dfg,MATCH
N100,2,Ferry,AI,,,,,Missing IN Right

DatsetAB-CD:
Joining criteria: userId and userName of A with C, userId and userName of B with D
userId,userName,age,contactNumber,orderId,orderDetails,userId,userName,status,departmentId,userId,userName,departmentName,userId,userName,address,pin,status,status
1,James,29,1111,DF23,Chocholate,1,James,MATCH,N99,1,James,DE,1,James,minland street,cvk-dfg,MATCH,MATCH
2,Ferry,32,2222,,,,,Missing IN Left,N100,2,Ferry,AI,,,,,Missing IN Right,Missing IN Right
如果数据定义为:

val-dfA=Seq((1,“James”,291111),(2,“Ferry”,3222),(3,“Lotus”,213333)).toDF(“用户ID,用户名,年龄,联系电话号码”。拆分(“,”):*
val dfB=Seq((“DF23”,“Chocholate”,1,“James”),(“DF45”,“Gifts”,3,“Lotus”)。toDF(“orderId,orderDetails,userId,userName”。拆分(“,”):*)
val dfC=Seq((“N99”,1,“James”,“DE”),(“N100”,2,“Ferry”,“AI”)).toDF(“部门ID,用户ID,用户名,部门名称”。拆分(“,”):*)
val dfD=Seq((1,“詹姆斯”、“明兰街”、“cvk dfg”)).toDF(“用户ID、用户名、地址、pin”。拆分(“,”):*)
定义关键点:

import org.apache.spark.sql.functions_
val keys=Seq(“用户ID”、“用户名”)
组合
数据集

val-dfs=Map(“A”->dfA,“B”->dfB,“C”->dfC,“D”->dfD)
val combined=dfs.map{
大小写(键,df)=>df.withColumn(“df”,lit(键))。选择(“df”,键:*)
}.reduce(\uUnionByName)
透视并将结果转换为布尔值:

val pivoted=组合
.groupBy(key.head、key.tail:*)
.pivot(“df”,dfs.keys.toSeq)
.count()
val result=dfs.keys.foldLeft(旋转)(
(df,c)=>df.withColumn(c,col(c).isNotNull.alias(c))
)
// +------+--------+----+-----+-----+-----+
//| userId | userName | A | B | C | D|
// +------+--------+----+-----+-----+-----+
//| 1 |詹姆斯|真|真|真|真|
//| 3 |莲花|真|真|假|假|
//| 2 | Ferry |真|假|真|假|
// +------+--------+----+-----+-----+-----+
使用生成的布尔矩阵生成最终报告

当数据集变大时,这可能会变得非常昂贵。如果您知道一个数据集包含所有可能的键,并且您不需要精确的结果(可以接受一些假阴性),那么可以使用Bloom filter

这里我们可以使用
dfA
作为参考:

val expectedNumItems=dfA.count
val fpp=0.00001
val key=struct(键映射列:*).cast(“字符串”).alias(“键”)
val filters=dfs.filterKeys(!=“A”).mapValues(df=>{
val f=df.select(键).stat.BLOOMPILTER(“键”,期望的数值,fpp);
自定义项((s:String)=>f.mightContain)
})
filters.foldLeft(dfA.select(键映射列:*)){
大小写(df,(c,f))=>df.withColumn(c,f(key))
}.表演
// +------+--------+-----+-----+-----+
//| userId | userName | B | C | D|
// +------+--------+-----+-----+-----+
//| 1 |詹姆斯|对|对|对|
//| 2 |摆渡|假|真|假|
//| 3 |莲花|真|假|假|
// +------+--------+-----+-----+-----+

到目前为止,您尝试了什么?请分享您的尝试。我尝试过合并两个数据集A、B和C、D,并在A、B和C、D之间存储状态。现在合并这两个数据集的结果,但处理起来越来越麻烦。您能更新问题中的数据集吗?请同时提及混乱的部分,谢谢你的解决方案。Bloom的过滤器解决方案无法工作,因为所有数据集可能都不完整。但你的第一个解决方案会奏效。我们可能会牺牲性能。
unionByName
union
几乎相同,但与列名匹配,而不是顺序匹配。您可以在此处安全地使用
union