如何连接两个RDD:value join不是org.apache.spark.rdd.RDD [org.apache.spark.sql.Row]的成员

时间:2017-07-10 07:48:38

标签: scala apache-spark importerror

我正在使用Spark 2.1.0和Scala 2.10.6

当我尝试这样做时:

val x = (avroRow1).join(flattened)

我收到错误:

value join is not a member of org.apache.spark.rdd.RDD[org.apache.spark.sql.Row]

为什么我会收到此消息?我有以下import语句:

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.rdd.RDD
import org.apache.spark.rdd.PairRDDFunctions

import org.apache.spark.sql._
import com.databricks.spark.avro._
import org.apache.spark.sql.functions.map
import org.apache.spark.sql.functions._
import org.apache.spark.sql.functions.col

这是我的代码:

 val avroRow = spark.read.avro(inputString).rdd
  val avroParsed = avroRow
    .map(x => new TRParser(x))
    .map((obj: TRParser) => {
      val tId = obj.source.trim
      var retVal: String = ""
      obj.ids
        .foreach((obj: TRUEntry) => {
          retVal += tId + "," + obj.uId.trim + ":"
        })
        retVal.dropRight(1)
    })

 val flattened = avroParsed
 .flatMap(x => x.split(":"))
 .map(y => ((y),1)).reduceByKey(_+_)  .map { case (a, b) => {
val Array(first, second) = a.split(",")
((first, second), b)
 }}.saveAsTextFile(outputString)


 val avroRow1 = spark.read.avro(inputString1).rdd
  val avroParsed1 = avroRow1
    .map(x => new TLParser(x))
    .map((obj: TLParser) => ((obj.source, obj.uid, obj.chmon))) .map { case (a, b, c) => ((a, b), c) }
    .saveAsTextFile(outputString1)


    val x = (avroParsed1).join(flattened)

更新

这是我的avroRow1示例输出:

((p872301075,fb_100004351878884),37500)
((p162506011,fb_100006956538970),-200000)

这是我展平的示例输出:

((p872301075,fb_100004351878884),2)
(p162506011,fb_100006956538970),1)

这是我想要获得的输出:

((p872301075,fb_100004351878884),37500,2)
(p162506011,fb_100006956538970),-200000,1)

3 个答案:

答案 0 :(得分:0)

val avroRow1 = spark.read.avro(inputString1).rdd

在这里,您要将DF转换为rdd。您应该将avroRow1转换为(键,值)对。然后应用连接操作。

答案 1 :(得分:0)

join() 操作仅适用于PairedRDD。在您的情况下,它不是配对的RDD。原因是,您需要一个公共密钥来连接两个RDD,但是使用通用RDD是不可能的。尝试将avroRow1 & flattened转换为(键,值),然后执行连接。

  

弹性分布式数据集(RDD),Spark中的基本抽象。   表示可以的不可变的分区元素集合   并行操作。该类包含基本操作   适用于所有RDD,例如map,filter和persist。此外,   org.apache.spark.rdd.PairRDDFunctions包含可用的操作   仅限于键值对的RDD,例如groupByKey和join;

答案 2 :(得分:0)

.saveAsTextFile(outputString)可能会导致问题,因为这会更改变量的返回类型。不是在加入之前保存为单个文件,RDD可以 persist(),并且最终输出可以通过这种方式由.saveAsTextFile保存: -

 val flattened = avroParsed
 .flatMap(x => x.split(":"))
 .map(y => ((y),1)).reduceByKey(_+_)  .map { case (a, b) => {
val Array(first, second) = a.split(",")
((first, second), b)
}}   


 val avroRow1 = spark.read.avro(inputString1).rdd
  val avroParsed1 = avroRow1
    .map(x => new TLParser(x))
    .map((obj: TLParser) => ((obj.source, obj.uid, obj.chmon))) .map { case (a, b, c) => ((a, b), c) }


val res = avroParsed1.join(flattened).saveAsTextFile(outputString1);