Spark SQL-столбец доступен после удаления

#scala #apache-spark #apache-spark-sql

#scala #apache-spark #apache-spark-sql

Вопрос:

Я пытаюсь понять, почему я могу фильтровать по столбцу, который я ранее отбросил.

Этот простой скрипт:

 package example

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions.col

object Test {

    def main(args: Array[String]): Unit = {
        val spark = SparkSession.builder()
            .appName("Name")
            .master("local[*]")
            .config("spark.driver.host", "localhost")
            .config("spark.ui.enabled", "false")
            .getOrCreate()
        
        import spark.implicits._

        List(("a0", "a1"), ("b0", "b1"))
            .toDF("column1", "column2")
            .drop("column2")
            .where(col("column2").startsWith("b"))
            .show()
    }
}

  

Показывает следующий вывод:

  ------- 
|column1|
 ------- 
|     b0|
 ------- 
  

Я ожидал увидеть некоторую ошибку, что «column2» недоступен, когда я пытаюсь его использовать .where(<condition>) .

Фрагмент из моего build.sbt :

 scalaVersion := "2.12.10"

libraryDependencies  = "org.apache.spark" %% "spark-sql" % "2.4.4" excludeAll ExclusionRule("org.apache.hadoop")
libraryDependencies  = "org.apache.hadoop" % "hadoop-client" % "3.2.1"
  

Есть ли какая-либо документация по этому поведению? И почему это вообще возможно?

Комментарии:

1. Это известная проблема в spark, посмотрите здесь: issues.apache.org/jira/browse/SPARK-30421

2. и здесь github.com/apache/spark/pull/27128

Ответ №1:

Это связано с тем, что sparks выталкивает фильтр / предикат, т. Е. spark оптимизирует запрос таким образом, что фильтр применяется перед «проекцией». То же самое происходит с select помощью вместо drop .

Это может быть полезно, поскольку фильтр может быть перенесен на данные:

введите описание изображения здесь