scala – 如何在连接中使用Column.isin和数组列?
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","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"))) 希望这个Scala代码片段能够清楚地说明我要完成的任务,我们的数据结构化使得一个数据集具有包含值数组的列,并且我希望将该集合中的值连接到另一个数据集.因此,例如ds1中的Seq(“A”,“B”)将与ds2中的“A”和“B”连接. Column上的“isin”运算符似乎正是我想要的,这构建并运行,但是当我运行它时,我收到以下错误:
进一步阅读我看到isin()想要采用varargs(“splatted args”)并且似乎更适合过滤器().所以我的问题是,这是这个运算符的预期用途,还是有其他方法来执行这种类型的连接? 解决方法
请使用array_contains:
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,D]|foo3| C| product C| |[B,D]|foo3| D| product D| | [C]|foo4| C| product C| | [C,D]|foo5| C| product C| | [C,D]|foo5| D| product D| +---------+----+----+-----------+ 如果使用Spark 1.x或2.0将crossJoin替换为标准连接,则替换为enable cross joins in configuration,if necessary. 有可能避免笛卡尔产品爆炸: ds1.withColumn("code",explode($"codes")).join(ds2,Seq("code")).show +----+---------+----+-----------+ |code| codes|name|description| +----+---------+----+-----------+ | B| [A,B]|foo2| product B| | B|[B,D]|foo3| product B| | D|[B,D]|foo3| product D| | D| [C,D]|foo5| product D| | C|[B,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| +----+---------+----+-----------+ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |