Spark Group By Key(String,Iterable <string>)

时间:2018-11-24 17:31:40

标签: java apache-spark apache-spark-sql

我正在尝试按键将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>>的原因吗?为了获得预期的结果,将进行哪些更改。

2 个答案:

答案 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应该相似。