根据key合并两个rdd有四种方式:
1.用SparkSQL进行join
2.用双重循环连接两个rdd
3.用rdd的join方法,如下所示,合并的key不能是Tuple
4.rdd中的元素仍然是键值对,只不过值是scala对象
Array中装的是Tuple,是键值对,建和值都是String类型
// 键是String类型,值是Tuple类型
val rdd1 = sc.makeRDD(Array(("1", ("Spark", "beijing")), ("2", ("Hadoop", "shanghai"))), 2)
// 下面的写法是错误的,值如果是一个容器,就要用括弧圈起来
val rdd1 = sc.makeRDD(Array(("1", "Spark", "beijing"), ("2", "Hadoop", "shanghai")), 2)
rdd进行join的key是String等基础数据类型,不能是Tuple等容器类
如果需要根据两个字段进行join,可以把两个字段连接起来作为一个新的字符串
package com.cheetah.offline
import java.io.File
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.spark.{SparkConf, SparkContext}
import scala.collection.mutable.HashMap
import scala.reflect.io.Directory
object RDDJoin {
val conf = new SparkConf().setMaster("local[*]").setAppName("qichecount")
var sc: SparkContext = null
def main(args: Array[String]) {
val conf = new SparkConf().setAppName("SparkRDDJoinOps").setMaster("local[4]")
val sc = new SparkContext(conf)
// 第一种写法Array(Tuple(String, Tuple))
val rdd1 = sc.makeRDD(Array(("1", ("Spark", "beijing")), ("2", ("Hadoop", "shanghai"))), 2)
// 注意键如果是Tuple是不行的,如下
// val rdd1 = sc.makeRDD(Array((("1001","type1"), ("Spark", "beijing")), (("1002", "type2"), ("Hadoop", "shanghai"))), 2)
// 创建rdd的另一种写法
// val idName = sc.parallelize(Array((1, "zhangsan"), (2, "lisi"), (3, "wangwu")))
val rdd2 = sc.makeRDD(Array(("1", "30K"), ("2", "15K"), ("3", "25K"), ("5", "10K")), 2)
println("//下面做Join操作,预期要得到(1,×)、(2,×)、(3,×)")
val joinRDD = rdd1.join(rdd2).collect.foreach(println)
println("//下面做leftOutJoin操作,预期要得到(1,×)、(2,×)、(3,×)、(4,×)")
val leftJoinRDD = rdd1.leftOuterJoin(rdd2).collect.foreach(println)
println("//下面做rightOutJoin操作,预期要得到(1,×)、(2,×)、(3,×)、(5,×)")
val rightJoinRDD = rdd1.rightOuterJoin(rdd2).collect.foreach(println)
sc.stop()
}
}