2017-08-30 56 views
0

我想让这个变量GroupsByP具有某种类型:GroupsByP是由db连接select/collect语句定义的,它有3个字段:2个字符串(pid)和一个int(order)。spark group by not getting type,mismatch error

预期的结果应该是这样的形式Map[p,Set[(Id,Order)]]

val GroupsByP = db.pLinkGroups.collect() 
    .groupBy(_.p) 
    .map(group => group._1 -> (group._2.map(_.Id -> group._2.map(_.Order)).toSet)) 

我期望这个变量的类型是

Map[String, Set[(String, Int)]] 

,但实际是Map[String, Set[(String, Array[Int])]],

回答

1

如果我收到了你的问题的权利,这应该做到这一点:

val GroupsByP: Map[String, Set[(String, Int)]] = input.collect() 
    .groupBy(_.p) 
    .map(group => group._1 -> group._2.map(record => (record.Id, record.Order)).toSet) 

您应该将每个记录映射到一个(Id, Order)元组。

一个非常类似的,但也许更易读的实现可能是:

val GroupsByP: Map[String, Set[(String, Int)]] = input.collect() 
    .groupBy(_.p) 
    .mapValues(_.map(record => (record.Id, record.Order)).toSet) 
+0

我认为做的。 QQ你怎么没有使用下划线,而是你使用记录? – dedpo

+0

使用下划线作为这样的匿名函数的输入参数,意味着你只能使用那个未命名的参数_once_ - 如果你尝试使用它两次(例如'(_.Id,_.Order)'),你实际上正在创建一个匿名函数需要**两个**参数(第一个下划线引用第一个下划线,第二个下划线引用第二个下划线)。这显然不是我们在这里需要的。换句话说,_naming_参数(在这里,我将它命名为“record” - 可以使用任何有意义的名称)通常是* must *。 Underscode是一种应该谨慎使用的短手。 –