【问题标题】:Spark Dataset joinWith API giving wrong resultsSpark Dataset joinWith API 给出错误结果
【发布时间】:2021-05-03 03:06:38
【问题描述】:

这是一个小测试用例,用于重现我在代码中加入时看到的问题

case class B(val b1:String, val b2: Int)
val B1 = new B("One",1)
val B2 = new B("Two",2)
val dsB = spark.createDataset(Seq(B1, B2))
dsB.show()
+---+---+
| b1| b2|
+---+---+
|One|  1|
|Two|  2|
+---+---+
val m = Map(1->"Van")
val mapget = spark.udf.register("mapget",  (b: Int) => m.get(b))
val dsB1 = dsB.withColumn("b2", mapget(dsB("b2"))).where("b2 is not null")
dsB1.show()
+---+---+
| b1| b2|
+---+---+
|One|Van|
+---+---+
val j = dsB1.joinWith(dsB, dsB1("b1") === dsB("b1"), "inner")
j.show()
+----------+--------+
|        _1|      _2|
+----------+--------+
|[One, Van]|[One, 1]|
|[One, Van]|[Two, 2]|
+----------+--------+

joinWith 结果不正确。它本质上是在做一个交叉产品。任何线索是什么问题?我已经验证join API 工作正常。

val j = dsB1.join(dsB, dsB1("b1") === dsB("b1"), "inner")
j.show()
+---+---+---+---+
| b1| b2| b1| b2|
+---+---+---+---+
|One|Van|One|  1|
+---+---+---+---+

【问题讨论】:

  • 我也收到了@Grisha_WeinTraub 提到的错误。如果您将内部联接更改为交叉,则它可以工作并给出您显示的输出。

标签: scala apache-spark apache-spark-sql apache-spark-dataset


【解决方案1】:

看起来您使用的是相当旧的 Spark 版本。 在 Spark 2.4.4 上,运行您的示例时出现以下异常:

org.apache.spark.sql.AnalysisException: Detected implicit cartesian product for INNER join between logical plans
LocalRelation [_1#55]
and
LocalRelation [_2#56]
Join condition is missing or trivial.

原因是连接条件实际上将dsB("b1") 与自身进行比较,这始终是正确的。

一个简单的解决方案是重命名该列。类似的东西:

val dsB1 = dsB.withColumn("b2", mapget(dsB("b2"))).where("b2 is not null").withColumnRenamed("b1", "b1_2")
val j = dsB1.joinWith(dsB, dsB1("b1_2") === dsB("b1"), "inner")
j.show
+----------+--------+
|        _1|      _2|
+----------+--------+
|[One, Van]|[One, 1]|
+----------+--------+

【讨论】:

  • 其实我有更新版本spark version 3.0.2.19Using Scala version 2.12.10 (OpenJDK 64-Bit Server VM, Java 1.8.0_242)
  • 还有任何关于为什么 join 有效而不是 joinWith 的原因
  • 看起来在 Spark 3.0 中不再抛出异常,您只得到笛卡尔连接结果 (SPARK-28621)。 joinjoinWith 之间的区别只是因为它现在的实现方式。有很多相关问题(例如 SPARK-6459、SPARK-25150、SPARK-20073),有些已完成,有些正在进行中,希望这一天也能修复。
猜你喜欢
  • 2017-11-04
  • 1970-01-01
  • 2023-04-07
  • 2014-09-16
  • 1970-01-01
  • 2011-11-15
  • 2019-02-06
  • 2014-01-30
  • 2018-08-01
相关资源
最近更新 更多