为什么有些运算符会创建不同类型的数据集,如RelationalGroupedDataset?

时间:2017-12-14 13:26:03

标签: apache-spark apache-spark-sql apache-spark-dataset

Dataset的某些运营商创建了新的Dataset并更新了逻辑计划,例如' filter'如下:

def filter(condition: Column): Dataset[T] = withTypedPlan {
  Filter(condition.expr, logicalPlan)
}

但是有些运营商(例如groupBy)会创建不同类型的Dataset,即RelationalGroupedDataset

为什么Spark没有使用可以表达groupBy的LogicalPlan创建新的数据集?

@scala.annotation.varargs
def groupBy(cols: Column*): RelationalGroupedDataset = {
  RelationalGroupedDataset(toDF(), cols.map(_.expr), RelationalGroupedDataset.GroupByType)
}

2 个答案:

答案 0 :(得分:2)

  • 因为groupBygroupByKey不是转换。它们只是更大变换的一个组成部分,包括:

    • 分组表达。
    • 聚合表达。
  • 可以对"分组数据执行的操作"与未经编组的数据"可以执行的数据不同而另一种方式。例如:

    • 您不能select来自分组数据,因为它不是最终状态(并不对应完整的物理RDD)。
    • 如果没有群组,您可以汇总或映射群组。

答案 1 :(得分:0)

我的理解是高级数据集API尝试尽可能接近SQL,因此读取一个应该很容易“显示”另一个,反之亦然。

在SQL中使用“GROUP BY”子句时,它表示没有结果,但表示数据集中的数据的逻辑分组。它类似于RDD API中的分区,它只是逻辑分区(和分发)数据集部分的一种方式。

SQL的“GROUP BY”本身就没有任何意义,你必须在分组上做某事,因此SELECT会给“环境”以对分组执行操作。

这与数据集API的Str.D非常吻合,您可以在其中指定分组的概念。它仅用于定义可以执行聚合的分组,从而用于通用RelationalGroupedDataset运算符。

有趣的是整个数据集是一个单独的组,因此您可以直接在agg上执行agg运算符(不Dataset,这相当于调用groupBy使用空的鉴别器功能)。