我正在尝试按键将urldata分组,其中值将为字符串
样本数据:
url_3 url_2
url_3 url_2
url_3 url_1
url_4 url_3
url_4 url_1
预期结果:
(url_3,(url_2,url_1))
(url_4,(url_3,url_1))
1)加载urldata:
Dataset<String> lines = spark.read()
.textFile("C:/Users/91984/workspace/myApp/src/test/resources/in/urldata.txt");
2)使用空格分割数据集
Encoder<Tuple2<String, String>> encoder2 =
Encoders.tuple(Encoders.STRING(), Encoders.STRING());
Dataset<Tuple2<String, String>> tupleRDD = lines.map(f->{
Tuple2<String, String> m =
new Tuple2<String, String>(f.split(" ")[0], f.split(" ")[1]);
return m;
},encoder2);
3)使用groupbyKey对基于key的tupleRDD数据库分组
KeyValueGroupedDataset<String, Tuple2<String, String>> keygrpDS =
tupleRDD.groupByKey(f->f._1, Encoders.STRING());
有人可以解释一下为什么第3步的groupByKey返回KeyValueGroupedDataset<String, Tuple2<String, String>>
而不是KeyValueGroupedDataset<String, Iterable<String>>
的原因吗?为了获得预期的结果,将进行哪些更改。
答案 0 :(得分:1)
这就是它与spark中的数据集一起使用的方式。当您拥有Dataset<T>
类型的数据集时,可以通过一些映射函数将其分组,该映射函数将获取类型为T的对象并返回类型为K(键)的对象。得到的是一个KeyValueGroupedDataset<K,T>
,可以在其上调用聚合函数(请参见the javadoc)。在您的情况下,可以使用mapGroups
,您可以向其提供将键K
和可迭代的Iterable<T>
映射到您选择的新对象R的函数。如果有帮助,在您的代码中,T是Tuple2,K是URL。
答案 1 :(得分:1)
Spark要求您使用groupBY
方法遵循aggregation
。我将把tupleRDD设为DataFrame
,例如:
column1 column2
url_3 url_2
url_3 url_2
url_3 url_1
url_4 url_3
url_4 url_1
并像这样传递collect_list(column2)
df.groupBy('column1').agg('column2', collect_list('column2'))
。
此示例在Python中。不过,Scala / Java API应该相似。