Scala 从返回类型为
我需要聚合3个不同的Scala 从返回类型为,scala,apache-spark,spark-dataframe,rdd,variadic-functions,Scala,Apache Spark,Spark Dataframe,Rdd,Variadic Functions,我需要聚合3个不同的rdd(在3个不同的迭代中),我正在使用map调用一个函数createKeyValuePair,该函数的返回类型为[((Long,Int,Int),a),((Int,Int,Int,Int),a)] 但是,reduceByKey不可用,它表示无法解析reduceByKey def createKeyValuePair(row: Row, data: String, elementsInKey: Int) : Either[((Long, Int, Int), A),
rdd
(在3个不同的迭代中),我正在使用map
调用一个函数createKeyValuePair
,该函数的返回类型为[((Long,Int,Int),a),((Int,Int,Int,Int),a)]
但是,reduceByKey
不可用,它表示无法解析reduceByKey
def createKeyValuePair(row: Row, data: String, elementsInKey: Int) : Either[((Long, Int, Int), A),
((Int, Int, Int, Int, Int), A)] = {
var keySet = Array[Long]()
for (i <- 0 to elementsInKey) {
keySet = keySet :+ row(i).asInstanceOf[Long]
}
val record = row(elementsInKey).asInstanceOf[A]
dataCut match {
case "string1" => return ... //(first key)
case "string2" => return ... //(second key)
}
null
}
然后reduceByKey
工作,但它认为返回类型只是((Long,Int),A)
,函数也显示错误,返回类型预期是(Long,Int)
,但实际是Seq[A]
问题2。在scala中不能将返回类型设为varargs吗?
注意:
reduceByKey
将应用的返回类型和数据具有相同的模式。我没有试图对具有不同模式的数据应用reduceByKey
。我将首先读取文件1和文件2,并将其聚合,其中键为(Long,Int,Int)
,然后在第二次迭代中,将读取第二个文件,其中键为(Int,Int,Int,Int)
,并将其聚合。reduceByKey
仅适用于(键,值)对的RDD,而您实际上没有(因为它们被包装在或中)
一个选项是从RDD[(Long,Int,Int),A),((Int,Int,Int,Int),A)]
更改为RDD[(Long,Int,Int),(Int,Int,Int),A)]
但是,我不认为您应该有一个createKeyValuePair
函数。在这两种情况下,您实际上共享的唯一代码是构建密钥数组。想象一下
def getKeyElements(row: Row, recordIndex: Int): List[Long] = {
(0 until recordIndex).map(row.getLong).toList
}
def createKeyValuePairFirstCase(row: Row): ((Long, Int, Int), A) = {
val first :: second :: third :: _ = getKeyElements(row, 3)
((first, second, third), row.get(3).asInstanceOf[A])
}
在第二种情况下也是如此,我相信(虽然我不确定也没有检查)您在键中得到了从Long
到Int
的隐式转换
一些随机注释:
- 我们需要
getKeyElements
返回一个列表
以使用第一个
、第二个
和第三个
,就像这样。您也可以只返回一个Seq
并使用索引构建元组
注意存在getLong
。还有getInt
和getString
等等
它确实感觉应该有一种方法来参数化键的类型并编写一个函数,但我不知道它是什么
您是否考虑过使用新的Dataset API?您也许可以使其更易于阅读,更健壮
嘿,解释得很好。谢谢。我不认为你应该有一个createKeyValuePair
。拥有一个函数的唯一原因是我想使用for
循环对3个不同的文件进行相同的聚合。两个有Long,Int,Int
,一个有(Int,Int,Int,Int,Int)
。我最后写了3篇不同的文章来阅读并汇总这3篇文章。
def createKeyValuePair(row: Row, data: String, elementsInKey: Int) : ((Long*, Int*), A) = {
var keySet = Array[Long]()
for (i <- 0 to elementsInKey) {
keySet = keySet :+ row(i).asInstanceOf[Long]
}
val record = row(elementsInKey).asInstanceOf[A]
((keySet: _*),record)
}
def getKeyElements(row: Row, recordIndex: Int): List[Long] = {
(0 until recordIndex).map(row.getLong).toList
}
def createKeyValuePairFirstCase(row: Row): ((Long, Int, Int), A) = {
val first :: second :: third :: _ = getKeyElements(row, 3)
((first, second, third), row.get(3).asInstanceOf[A])
}