我正在使用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)
答案 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);