Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 使用Spark Catalyst逻辑计划修改查询_Apache Spark_Apache Spark Sql - Fatal编程技术网

Apache spark 使用Spark Catalyst逻辑计划修改查询

Apache spark 使用Spark Catalyst逻辑计划修改查询,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,是否可以在中添加/替换现有列表达式 使用扩展点的DataFrameAPI/SQL 假设我们注入了可以检查项目的解析规则 节点,并在检查列名时替换它 例如,使用uppername 使用扩展点是否可以实现这种情况。我所举的例子 发现的大多数表达式都很简单,不能以我需要的方式操作输入表达式 请告诉我这是否可行。是的,这是可能的 让我们举个例子。假设我们想写一个规则来检查项目操作符,如果项目是针对某个特定的列,比如'column2',那么它将乘以2 import org.apache.spark.sql

是否可以在中添加/替换现有列表达式 使用扩展点的DataFrameAPI/SQL

假设我们注入了可以检查项目的解析规则 节点,并在检查列名时替换它 例如,使用uppername

使用扩展点是否可以实现这种情况。我所举的例子 发现的大多数表达式都很简单,不能以我需要的方式操作输入表达式

请告诉我这是否可行。

是的,这是可能的

让我们举个例子。假设我们想写一个规则来检查项目操作符,如果项目是针对某个特定的列,比如'column2',那么它将乘以2

import org.apache.spark.sql.catalyst.plans.logical._
import org.apache.spark.sql.catalyst.rules.Rule
import org.apache.spark.sql.catalyst.expressions._
import org.apache.spark.sql.catalyst.plans._
import org.apache.spark.sql.Column
import org.apache.spark.sql.types._

object DoubleColumn2OptimizationRule extends Rule[LogicalPlan] {
    def apply(plan: LogicalPlan): LogicalPlan = plan transform {
        case p: Project =>
          if (p.projectList.filter(_.name == "column2").size >= 1) {
              val newList = p.projectList.map { case x =>
                if (x.name == "column2") {
                  Alias(Multiply(Literal(2, IntegerType), x), "column2_doubled")()
                } else {
                  x
                }
              }
              p.copy(projectList = newList)
          } else {
              p
          }
    }
}
假设我们有一个表table1,它有两列——column1,column2

没有本条规则—

> spark.sql("select column2 from table1 limit 10").collect()
Array([1], [2], [3], [4], [5], [6], [7], [8], [9], [10])
> spark.experimental.extraOptimizations =  Seq(DoubleColumn2OptimizationRule)
> spark.sql("select column2 from table1 limit 10").collect()
Array([2], [4], [6], [8], [10], [12], [14], [16], [18], [20])
根据本条规则—

> spark.sql("select column2 from table1 limit 10").collect()
Array([1], [2], [3], [4], [5], [6], [7], [8], [9], [10])
> spark.experimental.extraOptimizations =  Seq(DoubleColumn2OptimizationRule)
> spark.sql("select column2 from table1 limit 10").collect()
Array([2], [4], [6], [8], [10], [12], [14], [16], [18], [20])
您也可以调用DataFrame上的explain来检查计划-

> spark.sql("select column2 from table1 limit 10").explain == Physical Plan == CollectLimit 10 +- *(1) LocalLimit 10 +- *(1) Project [(2 * column2#213) AS column2_doubled#214] +- HiveTableScan [column2#213], HiveTableRelation `default`.`table1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [column1#212, column2#213] 是的,这是可能的

让我们举个例子。假设我们想写一个规则来检查项目操作符,如果项目是针对某个特定的列,比如'column2',那么它将乘以2

import org.apache.spark.sql.catalyst.plans.logical._
import org.apache.spark.sql.catalyst.rules.Rule
import org.apache.spark.sql.catalyst.expressions._
import org.apache.spark.sql.catalyst.plans._
import org.apache.spark.sql.Column
import org.apache.spark.sql.types._

object DoubleColumn2OptimizationRule extends Rule[LogicalPlan] {
    def apply(plan: LogicalPlan): LogicalPlan = plan transform {
        case p: Project =>
          if (p.projectList.filter(_.name == "column2").size >= 1) {
              val newList = p.projectList.map { case x =>
                if (x.name == "column2") {
                  Alias(Multiply(Literal(2, IntegerType), x), "column2_doubled")()
                } else {
                  x
                }
              }
              p.copy(projectList = newList)
          } else {
              p
          }
    }
}
假设我们有一个表table1,它有两列——column1,column2

没有本条规则—

> spark.sql("select column2 from table1 limit 10").collect()
Array([1], [2], [3], [4], [5], [6], [7], [8], [9], [10])
> spark.experimental.extraOptimizations =  Seq(DoubleColumn2OptimizationRule)
> spark.sql("select column2 from table1 limit 10").collect()
Array([2], [4], [6], [8], [10], [12], [14], [16], [18], [20])
根据本条规则—

> spark.sql("select column2 from table1 limit 10").collect()
Array([1], [2], [3], [4], [5], [6], [7], [8], [9], [10])
> spark.experimental.extraOptimizations =  Seq(DoubleColumn2OptimizationRule)
> spark.sql("select column2 from table1 limit 10").collect()
Array([2], [4], [6], [8], [10], [12], [14], [16], [18], [20])
您也可以调用DataFrame上的explain来检查计划-

> spark.sql("select column2 from table1 limit 10").explain == Physical Plan == CollectLimit 10 +- *(1) LocalLimit 10 +- *(1) Project [(2 * column2#213) AS column2_doubled#214] +- HiveTableScan [column2#213], HiveTableRelation `default`.`table1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [column1#212, column2#213]
为什么要将项目属性名称转换为大写?你能告诉我这个用例吗?@prakharjain-我的用例是根据一些条件修改查询。无法更改客户端程序。所以现在就开始探索催化剂。大写字母只是一个例子。它可以是任何东西。@Bhanupalingrathore请检查下面的答案,看看这是否是您要查找的内容。为什么要将项目属性名称转换为大写?你能告诉我这个用例吗?@prakharjain-我的用例是根据一些条件修改查询。无法更改客户端程序。所以现在就开始探索催化剂。大写字母只是一个例子。它可能是任何东西。@Bhanupalingrathore请检查下面的答案,看看这是否是您要找的。谢谢您的详细回复。我使用的是COL上的UDF,而不是文字值。在我的案例中,使用AttributeExpression是个问题。不过我看了这个例子,并用alias包装了我的代码,效果很好。感谢您的详细回复。我使用的是COL上的UDF,而不是文字值。在我的案例中,使用AttributeExpression是个问题。不过,我确实查看了这个示例,并将代码包装在alias中,效果很好。