在Spark的旧的基于RDD的API中,可以在一次cogroup
调用中将多达3个RDD与原始RDD“共同分组”,假设它们都是具有相同密钥的RDD对。
在新的数据集API中,对于要分组的每个数据集,似乎必须调用两次groupByKey
,并一次调用cogroup
。
例如,假设我有一个包含最近活动数据的数据集和两个“元数据”数据集,它们用于为活动提供上下文,并且我希望将它们分组(历史记录和个人资料可以是大型结构,如果我将它们与活动一起加入,加入的数据集会变得不合理。这是我今天要做的:
// These data types all have an "id" field for correlation
val activityData: Dataset[Activity] = getActivity()
val locationHistory: Dataset[LocationHistory] = getLocationHistory()
val profiles: Dataset[Profile] = getProfiles()
// This first cogroup aligns activity with location history
val partialGroup = activityData.groupByKey(_.id)
.cogroup(locationHistory.groupByKey(_.id)) {
case (id, activity, location) if activity.nonEmpty =>
(id, activity, location)
case _ => None
}
// This second cogroup adds the profile to complete the grouping
val fullGroup = partialGroup.groupByKey(_._1)
.cogroup(profiles.groupByKey(_.id)) {
case (id, activityAndLocation, profile) =>
activityAndLocation.map { case(_, activity, location) =>
(id, activity, location, profile)
}
}
对于RDD API中的本质来说似乎有点长。在Dataset API中还有另一种方法不需要重复很多吗?