Scala 将键/值对列表转换为spark中每个键的值列表
我们需要高效地转换大量的键/值对列表,如下所示:Scala 将键/值对列表转换为spark中每个键的值列表,scala,apache-spark,combiners,Scala,Apache Spark,Combiners,我们需要高效地转换大量的键/值对列表,如下所示: val providedData = List( (new Key("1"), new Val("one")), (new Key("1"), new Val("un")), (new Key("1"), new Val("ein")), (new Key("2"), new Val("two")), (new Key("2"), new Val("deux")),
val providedData = List(
(new Key("1"), new Val("one")),
(new Key("1"), new Val("un")),
(new Key("1"), new Val("ein")),
(new Key("2"), new Val("two")),
(new Key("2"), new Val("deux")),
(new Key("2"), new Val("zwei"))
)
val expectedData = List(
(new Key("1"), List(
new Val("one"),
new Val("un"),
new Val("ein"))),
(new Key("2"), List(
new Val("two"),
new Val("deux"),
new Val("zwei")))
)
进入每个键的值列表,如下所示:
val providedData = List(
(new Key("1"), new Val("one")),
(new Key("1"), new Val("un")),
(new Key("1"), new Val("ein")),
(new Key("2"), new Val("two")),
(new Key("2"), new Val("deux")),
(new Key("2"), new Val("zwei"))
)
val expectedData = List(
(new Key("1"), List(
new Val("one"),
new Val("un"),
new Val("ein"))),
(new Key("2"), List(
new Val("two"),
new Val("deux"),
new Val("zwei")))
)
键-值对来自大型键/值存储(Accumulo),因此键将被排序,但通常会跨越spark分区边界。每个键可以有数百万个键和数百个值
我认为适合这项工作的工具是spark的combineByKey操作,但只能找到具有泛型类型(如Int)的简洁示例,而我无法将其推广到上述用户定义类型
由于我怀疑其他许多人也会有同样的问题,我希望有人能提供完整指定(详细)和简洁的scala语法示例,用于将combineByKey与上述用户定义类型一起使用,或者可能指出我错过的更好的工具。我不是真正的Spark专家,但基于,我认为你可以做到以下几点:
val rdd = sc.parallelize(providedData)
rdd.combineByKey(
// createCombiner: add first value to a list
(x: Val) => List(x),
// mergeValue: add new value to existing list
(acc: List[Val], x) => x :: acc,
// mergeCominber: combine the 2 lists
(acc1: List[Val], acc2: List[Val]) => acc1 ::: acc2
)
使用aggregateByKey
:
rdd.aggregateByKey(List[Val]())(
(acc, x) => x :: acc,
(acc1, acc2) => acc1 ::: acc2
)
六羟甲基三聚氰胺六甲醚;我得到这个:scala>r.collect res4:Array[(Key,List[Val])]=Array((1,List(ein)),(1,List(one)),(1,List(un)),(2,List(deux)),(2,List(two)),(2,List(zwei))@Bradjcox您实现了
Key
作为case类还是普通类?在后一种情况下,应该重写equals
方法。试试case-class-Key(Key:String)
这里是我正在使用的密钥类:@SerialVersionUID(123L)case-class-Key(v:String)扩展可序列化的{val n=v;override-def-toString:String={return n;}override-def-equals(o:Any)=o匹配{case-that:Key=>that.n.equals(this.n)case=>false}override def hashCode=n.hashCode}很抱歉出现错误警报。它作为编译代码运行良好,只是不在REPL中。我现在好了。谢谢在这种情况下,aggregateByKey
将起作用。不需要使用更复杂的签名。很抱歉误报。它作为编译代码运行良好,只是不在REPL中。我现在好了。谢谢这是一个悬而未决的问题