如何在scala spark中按键连接两个数据集

时间:2016-10-02 22:28:04

标签: scala apache-spark

我有两个数据集,每个数据集都有两个元素。 以下是示例。

数据1 :(姓名,动物)

('abc,def', 'monkey(1)')
('df,gh', 'zebra')
...

数据2 :(姓名,水果)

('a,efg', 'apple')
('abc,def', 'banana(1)')
...

预期结果:(名称,动物,水果)

('abc,def', 'monkey(1)', 'banana(1)')
... 

我想使用第一列'名称加入这两个数据集。'我已经尝试了几个小时,但我无法弄明白。任何人都可以帮助我吗?

val sparkConf = new SparkConf().setAppName("abc").setMaster("local[2]")
val sc = new SparkContext(sparkConf)
val text1 = sc.textFile(args(0))
val text2 = sc.textFile(args(1))

val joined = text1.join(text2)

以上代码无效!

2 个答案:

答案 0 :(得分:2)

join是在对的RDD上定义的,即RDD[(K,V)]类型的RDD。 需要的第一步是将输入数据转换为正确的类型。

我们首先需要将String类型的原始数据转换为(Key, Value)对:

val parse:String => (String, String) = s => {
  val regex = "^\\('([^']+)',[\\W]*'([^']+)'\\)$".r
  s match {
    case regex(k,v) => (k,v)
    case _ => ("","")
  }
}

(请注意,我们无法使用简单的split(",")表达式,因为该键包含逗号)

然后我们使用该函数来解析文本输入数据:

val s1 = Seq("('abc,def', 'monkey(1)')","('df,gh', 'zebra')")
val s2 = Seq("('a,efg', 'apple')","('abc,def', 'banana(1)')")

val rdd1 = sparkContext.parallelize(s1)
val rdd2 = sparkContext.parallelize(s2)

val kvRdd1 = rdd1.map(parse)
val kvRdd2 = rdd2.map(parse)

最后,我们使用join方法加入两个RDD

val joined = kvRdd1.join(kvRdd2)

//让我们查看结果

joined.collect

// res31: Array[(String, (String, String))] = Array((abc,def,(monkey(1),banana(1))))

答案 1 :(得分:0)

您必须首先为数据集创建pairRDD,然后必须应用连接转换。您的数据集看起来不准确。

请考虑以下示例。

**Dataset1**

a 1
b 2
c 3

**Dataset2**

a 8
b 4

您的代码应如下所示Scala

    val pairRDD1 = sc.textFile("/path_to_yourfile/first.txt").map(line => (line.split(" ")(0),line.split(" ")(1)))

    val pairRDD2 = sc.textFile("/path_to_yourfile/second.txt").map(line => (line.split(" ")(0),line.split(" ")(1)))

    val joinRDD = pairRDD1.join(pairRDD2)

    joinRDD.collect

以下是scala shell的结果

res10: Array[(String, (String, String))] = Array((a,(1,8)), (b,(2,4)))