Java spark groupByKey和groupedRDD上的do aggregateByKey和key2

Java spark groupByKey和groupedRDD上的do aggregateByKey和key2,java,apache-spark,Java,Apache Spark,我正在尝试做一个简单的JavaSpark应用程序,它执行以下操作 输入数据csv格式:key1、key2、data1、data2 基本上我想做的是 首先,我通过key1映射每一行,然后在该rdd上执行groupByKey操作 JavaRDD viewRdd=sc.textFile(“testfile.csv”,1); javapairdd customeridtorecordd=viewRdd .mapToPair(w->new Tuple2(w.split(“,”[0],w)); javapa

我正在尝试做一个简单的JavaSpark应用程序,它执行以下操作

输入数据csv格式:key1、key2、data1、data2

基本上我想做的是

首先,我通过key1映射每一行,然后在该rdd上执行groupByKey操作

JavaRDD viewRdd=sc.textFile(“testfile.csv”,1);
javapairdd customeridtorecordd=viewRdd
.mapToPair(w->new Tuple2(w.split(“,”[0],w));
javapairdd groupedByKey1RDD=customeridtorecorrdd.groupByKey();
System.out.println(customeridtorecordgropedd.count());
现在我的问题是,我需要在groupedByKey1RDD中的每个组上使用key2执行aggregateByKey。有没有办法将Iterable转换为RDD??或者我在这里遗漏了什么。我是新手,任何帮助都会很有用

输入和预期输出示例:

id_1,时间0,10,10

id_2,时间1,0,10

id_1,时间1,11,10

id_1,时间0,1,10

id_2,时间1,10,10

输出按第1列分组,然后按第2列聚合(聚合逻辑是简单地添加第3列和第4列):


下面是使用Spark 2.0和Dataframe的解决方案。如果您仍然想使用RDD,请告诉我

public class SparkGroupBySample {
    public static void main(String[] args) {
    //SparkSession
    SparkSession spark = SparkSession
            .builder()
            .appName("SparkGroupBySample")
            .master("local")
            .getOrCreate();     
    //Schema
    StructType schema = new StructType(new StructField[] { 
            new StructField("key1", DataTypes.StringType, true, Metadata.empty()),
            new StructField("key2", DataTypes.StringType, true, Metadata.empty()),
            new StructField("data1", DataTypes.IntegerType, true, Metadata.empty()),
            new StructField("data2", DataTypes.IntegerType, true, Metadata.empty())});
    //Read csv
    Dataset<Row> dataSet = spark.read().format("csv").schema(schema).option("header", "true").option("delimiter", ",").load("c:\\temp\\sample.csv");
    dataSet.show();     
    //groupBy and aggregate
    Dataset<Row> dataSet1 = dataSet.groupBy("key1","key2").sum("data1","data2").toDF("key1","key2","sum1","sum2");
    dataSet1.show();
    //stop
    spark.stop();
   }
}

下面是使用Spark 2.0和Dataframe的解决方案。如果您仍然想使用RDD,请告诉我

public class SparkGroupBySample {
    public static void main(String[] args) {
    //SparkSession
    SparkSession spark = SparkSession
            .builder()
            .appName("SparkGroupBySample")
            .master("local")
            .getOrCreate();     
    //Schema
    StructType schema = new StructType(new StructField[] { 
            new StructField("key1", DataTypes.StringType, true, Metadata.empty()),
            new StructField("key2", DataTypes.StringType, true, Metadata.empty()),
            new StructField("data1", DataTypes.IntegerType, true, Metadata.empty()),
            new StructField("data2", DataTypes.IntegerType, true, Metadata.empty())});
    //Read csv
    Dataset<Row> dataSet = spark.read().format("csv").schema(schema).option("header", "true").option("delimiter", ",").load("c:\\temp\\sample.csv");
    dataSet.show();     
    //groupBy and aggregate
    Dataset<Row> dataSet1 = dataSet.groupBy("key1","key2").sum("data1","data2").toDF("key1","key2","sum1","sum2");
    dataSet1.show();
    //stop
    spark.stop();
   }
}

您能提供csv数据样本和预期输出吗?@abaghel添加了样本输入和输出您使用的spark版本是什么?您是否希望使用RDD,因为使用Dataframe可以轻松解决此问题,并且更易于管理。您能否提供csv数据样本和预期输出?@abaghel添加了样本输入和输出您使用的spark版本是什么?您想使用RDD吗?因为使用Dataframe可以很容易地解决这个问题,并且更易于管理。非常感谢@abaghel。我以前没有使用过数据帧,所以对它知之甚少。我正在尝试使用更复杂的用户定义的聚合方法,而不是简单的求和,我相信我们也可以使用数据帧。但是如果可能的话,我想知道我们如何用RDD实现同样的目标。我使用的是spark 2.0,spark 2.0应该使用数据帧。是的,您可以通过将内置函数传递给agg方法来进行不同类型的聚合,也可以调用用户定义的函数。请检查“org.apache.spark.sql.functions”。示例-dataSet.groupBy(“c1”).agg(org.apache.spark.sql.functions.collect_list(“c2”);我试图用一些额外的派生值聚合并创建一个新的pojo。可以使用数据帧吗?谢谢基本上,我所寻找的输出类似于{map of key1:{map of key2:[聚合POJO列表]}。如果您有来自输入数据的数据帧,您可以调用map或flatmap函数来创建所需的输出。您甚至可以通过在输入数据上创建临时表来运行SQL查询。请查看更多详细信息。非常感谢@abaghel。我以前没有使用过数据帧,所以对它知之甚少。我正在尝试使用更复杂的用户定义的聚合方法,而不是简单的求和,我相信我们也可以使用数据帧。但是如果可能的话,我想知道我们如何用RDD实现同样的目标。我使用的是spark 2.0,spark 2.0应该使用数据帧。是的,您可以通过将内置函数传递给agg方法来进行不同类型的聚合,也可以调用用户定义的函数。请检查“org.apache.spark.sql.functions”。示例-dataSet.groupBy(“c1”).agg(org.apache.spark.sql.functions.collect_list(“c2”);我试图用一些额外的派生值聚合并创建一个新的pojo。可以使用数据帧吗?谢谢基本上,我所寻找的输出类似于{map of key1:{map of key2:[聚合POJO列表]}。如果您有来自输入数据的数据帧,您可以调用map或flatmap函数来创建所需的输出。您甚至可以通过在输入数据上创建临时表来运行SQL查询。请查看更多详细信息。
+----+-----+----+----+
|key1| key2|sum1|sum2|
+----+-----+----+----+
|id_1|time1|  11|  10|
|id_2|time1|  10|  20|
|id_1|time0|  11|  20|
+----+-----+----+----+