Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala Spark:将EbyKey聚合为一对列表_Scala_Apache Spark_Aggregation - Fatal编程技术网

Scala Spark:将EbyKey聚合为一对列表

Scala Spark:将EbyKey聚合为一对列表,scala,apache-spark,aggregation,Scala,Apache Spark,Aggregation,我有一组包含图书id和读者id字段的键控记录 case class Book(book: Int, reader: Int) 如何使用aggregateByKey将具有相同键的所有记录合并为一个以下格式的记录: (key:Int, (books: List:[Int], readers: List:[Int])) 其中books是所有书籍的列表,readers是具有给定键的记录中所有读者的列表 我的代码(如下)导致编译错误: import org.apache.log4j.{Level,

我有一组包含图书id和读者id字段的键控记录

case class Book(book: Int, reader: Int)
如何使用
aggregateByKey
将具有相同键的所有记录合并为一个以下格式的记录:

(key:Int, (books: List:[Int], readers: List:[Int])) 
其中books是所有书籍的列表,readers是具有给定键的记录中所有读者的列表

我的代码(如下)导致编译错误:

import org.apache.log4j.{Level, Logger}
import org.apache.spark.{SparkContext, SparkConf}

object Aggr {

  case class Book(book: Int, reader: Int)

  val bookArray = Array(
      (2,Book(book = 1, reader = 700)),
      (3,Book(book = 2, reader = 710)),
      (4,Book(book = 3, reader = 710)),
      (2,Book(book = 8, reader = 710)),
      (3,Book(book = 1, reader = 720)),
      (4,Book(book = 2, reader = 720)),
      (4,Book(book = 8, reader = 720)),
      (3,Book(book = 3, reader = 730)),
      (4,Book(book = 8, reader = 740))
  )

  def main(args: Array[String]) {
    Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
    Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF)
    // set up environment
    val conf = new SparkConf()
      .setMaster("local[5]")
      .setAppName("Aggr")
      .set("spark.executor.memory", "2g")
    val sc = new SparkContext(conf)

    val books = sc.parallelize(bookArray)
    val aggr = books.aggregateByKey((List()[Int], List()[Int]))
    ({case
      ((bookList:List[Int],readerList:List[Int]), Book(book, reader)) =>
      (bookList ++ List(book), readerList ++ List(reader))
      },
    {case ((bookLst1:List[Int], readerLst1:List[Int]),
    (bookLst2:List[Int], readerLst2:List[Int])
      ) => (bookLst1 ++ bookLst2, readerLst1 ++ readerLst2) })


  }
}
错误:

Error:(36, 44) object Nil does not take type parameters.
val aggr = books.aggregateByKey((List()[Int], List()[Int]))

Error:(37, 6) missing parameter type for expanded function The argument types of an anonymous function must be fully known. (SLS 8.5) Expected type was: ?
({case
 ^
                                       ^
更新

使用
(列表(0)初始化accumalator时,列表(0)
所有内容都会编译,但会在结果中插入额外的零。非常有趣:

val aggr :  RDD[(Int, (List[Int], List[Int]))] = books.aggregateByKey((List(0), List(0))) (
{case
  ((bookList:List[Int],readerList:List[Int]), Book(book, reader)) =>
  (bookList ++ List(book), readerList ++ List(reader))
  },
{case ((bookLst1:List[Int], readerLst1:List[Int]),
(bookLst2:List[Int], readerLst2:List[Int])
  ) => (bookLst1 ++ bookLst2, readerLst1 ++ readerLst2) }
)
这将产生以下输出:

[Stage 0:>                                                          (0 + 0) / 5](2,(List(0, 1, 0, 8),List(0, 700, 0, 710)))
(3,(List(0, 2, 0, 1, 0, 3),List(0, 710, 0, 720, 0, 730)))
(4,(List(0, 3, 0, 2, 8, 0, 8),List(0, 710, 0, 720, 720, 0, 740)))
如果我可以将空列表作为初始值设定项,而不是带有零的列表,我就不会有额外的零,当然,列表会很好地连接起来


有人能解释一下为什么空列表初始值设定项
(list(),list()
会导致错误,并且
(list(0),list(0)
会编译。这是Scala错误还是功能?

实际上你做的一切都很好,只是你的缩进/语法风格有点马虎,你只需要从这里移一个括号:

val aggr = books.aggregateByKey((List()[Int], List()[Int]))
({case
为此:

val aggr = books.aggregateByKey((List[Int](), List[Int]())) (
    {case
这些链接可能会说明为什么这对您不起作用:

(第一个答案)


回答更新-您将列表的类型声明放错了位置。如果您将列表声明为
List[Int]()
而不是
List()[Int]
,则一切都会正常工作。编译器错误消息正确地告诉了您问题所在,但不太容易理解。通过放置
[Int]
最后,您将类型参数传递给
List()
函数的结果
List()
的结果是
Nil
——一个表示空列表的单例对象,并且它不接受类型参数

至于为什么
List(0)
也能起作用——如果可以的话,scala会执行类型推断。您已经声明了列表的一个元素,即0,一个整数,因此它推断这是一个
List[Int]
。但是,请注意,这并不是声明一个空列表,而是一个具有单个零的列表。您可能希望使用
List[Int]()


仅使用
List()
不起作用,因为scala无法推断空列表的类型。

谢谢!不幸的是,在应用更正后,您建议我仍然得到相同的
错误:(34,44)object Nil不接受类型参数。val aggr=books.aggregateByKey((List()[Int],List()[Int]))(
^@zork啊是的,很抱歉我复制了你的代码,而不是我在编译器中更改的代码,并且忘了提及它,无论如何Zoltan已经指出了这一点,但我将更改
[Int]
declaration tooThanks!Scala类型声明和多行声明,括号放在错误的行上,哦,天哪!我使用Scala越多,Haskell的值就越大。