我需要在Scala中使用自己的类作为键/值对中的键。具体来说,我有一个简单的类,它保存两个变量"id1"和"id2",我希望元素仅基于"id2"而不是"id1"进行分组。我无法在网上找到任何关于如何覆盖"reduceByKey()"方法的比较方法以便根据我的自定义"compare()"方法分组具有相同键的元素的信息。
欢迎提供任何帮助。 谢谢。
欢迎提供任何帮助。 谢谢。
reduceByKey
的比较方法,因为它将无法利用数据通常在集群中的不同执行器上按键进行分组的事实。但你可以更改键(并注意根据你使用的转换/操作,这很可能会重新分组数据)。RDD中有一个巧妙的方法可以做到这一点,叫做keyBy
,所以你可以像这样做:val data: RDD[MyClass] = ... // Same code you have now.
val byId2 = data.keyBy(_.id2) //Assuming your ids are Longs, will produce a RDD[(Long,MyClass)]
reduceByKey
会使用equals
和hashCode
。因此,您可以确保这些方法被定义,并且这将导致正确的比较被使用。你不能只是map
一下RDD
,让键值对的第一个元素成为你想要使用的键吗?
case class MyClass(id1: Int, id2: Int)
val rddToReduce: Rdd[(MyClass, String)] = ... //An RDD with MyClass as key
rddToReduce.map {
case (MyClass(id1, id2), value) => (id2, (id1, value)) //now the key is id2
} .reduceByKey {
case (id1, value) => //do the combination here
...
} .map {
case (id2, (id1, combinedValue)) =>
(MyClass(id1, id2), combinedValue) //rearrange so that MyClass is the key again
}
id1
。但是你必须放弃一些 id1
- 考虑一下如果你有两个具有相同 id2
但不同 id1
的条目会发生什么?你只能得到一个元素(因为它们具有相同的 id2
被合并),所以你只能得到一个 id1
。 - lmm