Scala 为什么';编译器不会因为spark列表达式不是BooleanType而引发错误吗?
我有以下情况:Scala 为什么';编译器不会因为spark列表达式不是BooleanType而引发错误吗?,scala,dataframe,apache-spark,Scala,Dataframe,Apache Spark,我有以下情况: import org.apache.spark.sql.{Column, DataFrame} import org.apache.spark.sql.functions._ case class A(name: String) val df = List(A("sasha"),A("")).toDF // deliberately writing a non boolean expression def getFil
import org.apache.spark.sql.{Column, DataFrame}
import org.apache.spark.sql.functions._
case class A(name: String)
val df = List(A("sasha"),A("")).toDF
// deliberately writing a non boolean expression
def getFilterExpr: Column = regexp_replace(col("name").isNotNull && col("name") === "sasha" ,"","")
object Test { def Filter(df:DataFrame):DataFrame = df.filter(getFilterExpr) }
尽管getFilterExpr
不是booleanstype
,但上面的代码还是编译的。只有在调用Filter(df)
时,才会引发火花分析异常
我的问题是,
列
(如上所述)使用单独的方法返回过滤器表达式。这是一个好方法吗?我的怀疑是因为列
封装了一个表达式
,在构建复合表达式时,结果是一个列
而不是一个表达式,这对我来说有点不直观我认为这是因为
getFilterExpr
不返回boolead,而是返回您定义的列。过滤器用于过滤与给定条件不匹配的值,因此如果要保留值,它必须返回true
,否则必须返回false
一个有效的过滤器
用法示例(我不知道spark,所以我会假装你没有调用toDF
):
df.filter(a=>!a.name.isEmpty)
此筛选器将保留所有非空实例。从您的代码判断,您很有可能打算使用map
而不是filter
val df=spark.read.parquet(“路径到数据框”)
df.过滤器(柱(“拼花地板中的a柱”))
其结果将完全取决于拼花地板中的立柱。如果它是一个布尔列,那么一切都会顺利进行。如果它不是布尔值,您将得到一个错误。在编译时无法知道列的类型(在这种情况下,如果拼花文件更改,它可能在执行之间更改)。所以不,这里不能出现编译时错误
def getFilterExpression:列=???
我认为如果过滤器表达式比较复杂,这将是一个好主意。Spark数据帧是非类型化的,这意味着所有错误都将在运行时发生。如果您想要更安全的东西,可以使用数据集。在这种情况下,唯一可能的运行时错误是在读取数据时(这是代码的第一步,因此不是那么糟糕)。不利的一面是,您必须使用cases类对所有数据进行建模,这可能很繁琐。