我已尝试解决已应用的cogroup
问题。但我真的不知道......
如果有两个具有不同密钥的RDD,如下例所示,是否可以仅在使用data1
的第一个单词相同时提取有效cogroup
?
val data1 = sc.parallelize(Seq(("aa", 1), ("ba", 2), ("bc", 2), ("b", 3), ("c", 1)))
val data2 = sc.parallelize(Seq(("a", 3), ("b", 5)))
val cogroupRdd: RDD[(String, (Iterable[Int], Iterable[Int]))] = data1.cogroup(data2)
/* List(
(ba,(CompactBuffer(2),CompactBuffer())),
(bc,(CompactBuffer(2),CompactBuffer())),
(a,(CompactBuffer(),CompactBuffer(3))),
(b,(CompactBuffer(3),CompactBuffer(5))),
(c,(CompactBuffer(1),CompactBuffer())),
(aa,(CompactBuffer(1),CompactBuffer()))
) */
结果应为Array(("aa", 1), ("ba", 2), ("bc", 2), ("b", 3))
我使用broadcast()
解决了这个问题,因为@mrsrinivas说。
但broadcast()
不适合大数据。
val bcast = sc.broadcast(data2.map(_._1).collect())
val result = data1.filter(r => bcast.value.contains(myFuncOper(r._1)))
是否有使用cogroup
功能操作解决此问题的方法?
答案 0 :(得分:1)
您可以在提取与cogroup
键匹配的密钥后使用data2
,然后使用filter
和map
删除没有匹配的值和“重组”数据:
val result: RDD[(String, Int)] = data1
.keyBy(_._1.substring(0, 1)) // key by first character
.cogroup(data2)
.filter { case (_, (_, data2Values)) => data2Values.nonEmpty }
.flatMap { case (_, (data1Values, _)) => data1Values }
答案 1 :(得分:1)
<强>短强>
val result = data1
.flatMap(x => x._1.split("").map(y => (y, x)))
.join(data2)
.map(x => x._2._1)
.distinct
<强>详细说明:强>
flatMap(x => x._1.split("").map(y => (y, x)))
持有
List(
(a, (aa, 1)),
(a, (aa, 1)),
(b, (ba, 2)),
(a, (ba, 2)),
(b, (bc, 2)),
(c, (bc, 2)),
(b, (b, 3)),
(c, (c, 1))
)
在join(data2)
之后
List(
(a, ((aa, 1), 3)),
(a, ((aa, 1), 3)),
(a, ((ba, 2), 3)),
(b, ((ba, 2), 5)),
(b, ((bc, 2), 5)),
(b, ((b, 3), 5))
)
现在我们所有人都对不同的第二对第一对感兴趣,可以通过map(x => x._2._1).distinct