...通过检查是否有列'值在seq
也许我没有很好地解释它,我基本上想要这个(用常规SQL来表达它):DF_Column IN seq
?
首先,我使用broadcast var
(我放置了seq),UDF
(进行了检查)和registerTempTable
。
问题是我没有测试它,因为我遇到known bug,显然只有在使用 ScalaIDE registerTempTable
时才会出现。
我最终在DataFrame
中创建了一个新的seq
并与它进行内连接(交集),但我怀疑这是完成任务的最佳方式。
由于
编辑:(回应@YijieShen):
如何根据一个filter
列中的元素是否在另一个DF列(如SQL DataFrame
)中来select * from A where login in (select username from B)
?
E.g: 第一次DF:
login count
login1 192
login2 146
login3 72
第二次DF:
username
login2
login3
login4
结果:
login count
login2 146
login3 72
尝试:
EDIT-2:我认为,现在修复了错误,这些应该可行。 END EDIT-2
ordered.select("login").filter($"login".contains(empLogins("username")))
和
ordered.select("login").filter($"login" in empLogins("username"))
分别抛出Exception in thread "main" org.apache.spark.sql.AnalysisException
:
resolved attribute(s) username#10 missing from login#8 in operator
!Filter Contains(login#8, username#10);
和
resolved attribute(s) username#10 missing from login#8 in operator
!Filter login#8 IN (username#10);
答案 0 :(得分:16)
我的代码(按照第一种方法的描述)在这两种配置的Spark 1.4.0-SNAPSHOT
中正常运行:
Intellij IDEA's test
Spark Standalone cluster
有8个节点(1个主人,7个工人)请检查是否存在差异
val bc = sc.broadcast(Array[String]("login3", "login4"))
val x = Array(("login1", 192), ("login2", 146), ("login3", 72))
val xdf = sqlContext.createDataFrame(x).toDF("name", "cnt")
val func: (String => Boolean) = (arg: String) => bc.value.contains(arg)
val sqlfunc = udf(func)
val filtered = xdf.filter(sqlfunc(col("name")))
xdf.show()
filtered.show()
<强>输出强>
姓名cnt
login1 192
login2 146
login3 72
姓名cnt
login3 72
答案 1 :(得分:12)
您应该广播Set
,而不是Array
,搜索速度比线性搜索快得多。
您可以让Eclipse运行您的Spark应用程序。以下是:
正如邮件列表中所指出的,spark-sql假定其类由原始类加载器加载。 Eclipse中的情况并非如此,Java和Scala库是作为引导类路径的一部分加载的,而用户代码及其依赖项是另一个。您可以在启动配置对话框中轻松修复它:
scala-reflect
,scala-library
和scala-compiler
。对话框应如下所示:
修改:Spark bug已修复,不再需要此解决方法(自1.4.4版起)