Scala 如何将Column.isin与联接中的数组列一起使用?

Scala 如何将Column.isin与联接中的数组列一起使用?,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,希望这个Scala代码片段清楚地说明了我要完成的工作,我们的数据是结构化的,这样一个数据集就有一个包含值数组的列,我希望将该集合中的值连接到另一个数据集。因此,例如ds1中的Seq(“A”,“B”)将与ds2中的“A”和“B”连接 列上的“isin”操作符似乎正是我想要的,它构建并运行,但当我运行它时,我得到以下错误: org.apache.spark.sql.AnalysisException:由于数据类型不匹配,无法解析(code)中的“(code)”:参数的类型必须相同 进一步阅读,我发现

希望这个Scala代码片段清楚地说明了我要完成的工作,我们的数据是结构化的,这样一个数据集就有一个包含值数组的列,我希望将该集合中的值连接到另一个数据集。因此,例如
ds1
中的
Seq(“A”,“B”)
将与
ds2中的
“A”
“B”
连接

列上的“isin”操作符似乎正是我想要的,它构建并运行,但当我运行它时,我得到以下错误:

org.apache.spark.sql.AnalysisException:由于数据类型不匹配,无法解析(
code
)中的“(
code
)”:参数的类型必须相同


进一步阅读,我发现
isin()
想要使用varargs(“飞溅的args”),并且似乎更适合
过滤器()
。所以我的问题是,这是这个操作符的预期用途,还是有其他方法来执行这种类型的连接

请使用
数组\u contains

case class Foo1(codes:Seq[String], name:String)
case class Foo2(code:String, description:String)

val ds1 = Seq(
  Foo1(Seq("A"),           "foo1"),
  Foo1(Seq("A", "B"),      "foo2"),
  Foo1(Seq("B", "C", "D"), "foo3"),
  Foo1(Seq("C"),           "foo4"),
  Foo1(Seq("C", "D"),      "foo5")
).toDS

val ds2 = Seq(
  Foo2("A", "product A"),
  Foo2("B", "product B"),
  Foo2("C", "product C"),
  Foo2("D", "product D"),
  Foo2("E", "product E")
).toDS

val j = ds1.join(ds2, ds2("code") isin (ds1("codes")))
如果使用Spark 1.x或2.0,请将
交叉连接
替换为标准连接,然后

使用
explode
可以避免笛卡尔积:

ds1.crossJoin(ds2).where("array_contains(codes, code)").show

+---------+----+----+-----------+
|    codes|name|code|description|
+---------+----+----+-----------+
|      [A]|foo1|   A|  product A|
|   [A, B]|foo2|   A|  product A|
|   [A, B]|foo2|   B|  product B|
|[B, C, D]|foo3|   B|  product B|
|[B, C, D]|foo3|   C|  product C|
|[B, C, D]|foo3|   D|  product D|
|      [C]|foo4|   C|  product C|
|   [C, D]|foo5|   C|  product C|
|   [C, D]|foo5|   D|  product D|
+---------+----+----+-----------+
ds1.withColumn("code", explode($"codes")).join(ds2, Seq("code")).show
+----+---------+----+-----------+                                               
|code|    codes|name|description|
+----+---------+----+-----------+
|   B|   [A, B]|foo2|  product B|
|   B|[B, C, D]|foo3|  product B|
|   D|[B, C, D]|foo3|  product D|
|   D|   [C, D]|foo5|  product D|
|   C|[B, C, D]|foo3|  product C|
|   C|      [C]|foo4|  product C|
|   C|   [C, D]|foo5|  product C|
|   A|      [A]|foo1|  product A|
|   A|   [A, B]|foo2|  product A|
+----+---------+----+-----------+