我是Sacla和Spark的新手,我尝试使用jdbcRDD使用Spark在SqlServer上创建SQL查询,并使用映射和聚合对其进行一些转换。 这就是我所拥有的,一个包含n个String列和m个Number列的表。 像
"A", "A1",1,2
"A", "A1",4,3
"A", "A2",3,4
"B", "B1",6,7
...
...
我正在寻找的是创建一个分层结构,将字符串分组并聚合数字列,如
A
|->A1
|->(5,5)
|->A2
|->(3,4)
B
|->B1
|->(6,7)
我能够创建hierarchie但我无法在数值列表中执行聚合。
答案 0 :(得分:1)
如果您通过JDBC加载数据,我只需使用DataFrames:
import sqlContext.implicits._
import org.apache.spark.sql.functions.sum
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.DataFrame
val options: Map[(String, String)] = ???
val df: DataFrame = sqlContext.read
.format("jdbc")
.options(options)
.load()
.toDF("k1", "k2", "v1", "v2")
df.printSchema
// root
// |-- k1: string (nullable = true)
// |-- k2: string (nullable = true)
// |-- v1: integer (nullable = true)
// |-- v2: integer (nullable = true)
df.show
// +---+---+---+---+
// | k1| k2| v1| v2|
// +---+---+---+---+
// | A| A1| 1| 2|
// | A| A1| 4| 3|
// | A| A2| 3| 4|
// | B| B1| 6| 7|
// +---+---+---+---+
使用上面的输入,您只需要一个基本的聚合
df
.groupBy($"k1", $"k2")
.agg(sum($"v1").alias("v1"), sum($"v2").alias("v2")).show
// +---+---+---+---+
// | k1| k2| v1| v2|
// +---+---+---+---+
// | A| A1| 5| 5|
// | A| A2| 3| 4|
// | B| B1| 6| 7|
// +---+---+---+---+
如果你有这样的RDD:
val rdd RDD[(String, String, Int, Int)] = ???
rdd.first
// (String, String, Int, Int) = (A,A1,1,2)
没有理由构建复杂的层次结构。简单的PairRDD
应该足够了:
val aggregated: RDD[((String, String), breeze.linalg.Vector[Int])] = rdd
.map{case (k1, k2, v1, v2) => ((k1, k2), breeze.linalg.Vector(v1, v2))}
.reduceByKey(_ + _)
aggregated.first
// ((String, String), breeze.linalg.Vector[Int]) = ((A,A2),DenseVector(3, 4))
保持层次结构无效,但您可以将RDD
组合在一起,如下所示:
aggregated.map{case ((k1, k2), v) => (k1, (k2, v))}.groupByKey