Spark(Scala)中的灵活加入条件

时间:2019-03-11 17:43:56

标签: scala apache-spark join

我想要一个灵活的连接条件,例如可以作为字符串(或任何其他建议?)传递。例如,在以下语句中,FLEXIBLE_CONDITION表达式可以在不同的运行中更改。

val df3 = df1.join(df2, FLEXIBLE_CONDITION, "fullouter")

几个例子:

 (1) df1(s"query") === df2 (s"query_df2") 
 (2) df1(s"id") === df2(s"id_df2") && df1(s"item") === df2(s"item_df2")
 (3) Or combination of (1) and (2) or any other condition

需要注意的是,连接的列名将基于它们而不同。例如,在(1)中,在df1中,列名是query,在df2中,列名是query_df2,依此类推。

FLEXIBLE_CONDITION不应进行硬编码,但可以作为输入,并且可能会经常更改。或者可以根据一组输入(例如列名)自动执行。

2 个答案:

答案 0 :(得分:0)

您可以提供表达式,该表达式应在join中使用

为此签名

def join(right: Dataset[_], joinExprs: Column): DataFrame

例如

val df1 = Seq(
    ("a1", "b1"),
    ("a2", "b2")
).toDF("a", "b")

val df2 = Seq(
    ("b1", "a1"),
    ("b2", "a2")
).toDF("b1", "a1")

df1.show
df2.show

输出

+---+---+
|  a|  b|
+---+---+
| a1| b1|
| a2| b2|
+---+---+

+---+---+
| b1| a1|
+---+---+
| b1| a1|
| b2| a2|
+---+---+

您可以构建任何想要蚂蚁提供的表达式以供加入

val expression = df1("a") === df2("a1")
val result = df1 join (df2, expression)

result.show

输出

+---+---+---+---+
|  a|  b| b1| a1|
+---+---+---+---+
| a1| b1| b1| a1|
| a2| b2| b2| a2|
+---+---+---+---+

UPD:

您可以使用createOrReplaceTempView 例如

df1.createOrReplaceTempView("df1")
df2.createOrReplaceTempView("df2")

val res = spark.sql("select * from df1 inner join df2 on df1.a == df2.a1")
res.show

输出

+---+---+---+---+
|  a|  b| b1| a1|
+---+---+---+---+
| a1| b1| b1| a1|
| a2| b2| b2| a2|
+---+---+---+---+

结果将相同,您可以提供SQL查询作为字符串

答案 1 :(得分:0)

我知道了。这就是我想要的:

 val first :  String = unique_attrs(0)
 var expression : org.apache.spark.sql.Column = df1(first) === df2_r(s"$first" + "_df2")
 for (i <- 1 to unique_attrs.length - 1) {
   val attr : String = unique_attrs(1)
   expression = expression && df1(attr) === df2_r(s"$attr" + "_df2")
 }

 val df3 = df1.join(df2_r, expression, "fullouter")

属性列表作为方法的输入(唯一性)提供。