SparkSQL+;Java:Pojo在处理数据集时转换为表格格式

SparkSQL+;Java:Pojo在处理数据集时转换为表格格式,java,apache-spark,apache-spark-sql,apache-spark-dataset,Java,Apache Spark,Apache Spark Sql,Apache Spark Dataset,我对Spark SQL很陌生。在执行一项培训任务时,我遇到了以下问题,无法找到答案(以下所有示例都有点愚蠢,但出于演示目的,应该仍然可以) 我的应用程序读取拼花地板文件并根据其内容创建数据集: DataFrame input = sqlContext.read().parquet("src/test/resources/integration/input/source.gz.parquet"); Dataset<Row> dataset = input.as(RowEncoder$.

我对Spark SQL很陌生。在执行一项培训任务时,我遇到了以下问题,无法找到答案(以下所有示例都有点愚蠢,但出于演示目的,应该仍然可以)

我的应用程序读取拼花地板文件并根据其内容创建数据集:

DataFrame input = sqlContext.read().parquet("src/test/resources/integration/input/source.gz.parquet");
Dataset<Row> dataset = input.as(RowEncoder$.MODULE$.apply(input.schema()));
然后,我将数据集转换为一个新的数据集,其中包含Person类型:

public static Dataset<Person> transformToPerson(Dataset<Row> rawData) {
    return rawData
            .flatMap((Row sourceRow) -> {
                // code to parse an input row and split person data goes here
                Person person1 = new Person(name1, gender1, age1);
                Person person2 = new Person(name2, gender2, age2);
                return Arrays.asList(person1, person2);
            }, Encoders.bean(Person.class));
}
然而,我明白了

+-------------------+----------------+--------+
+      name         +       gender   +   age  +
+-------------------+----------------+--------+
|(Jack, Male, 30)   |                |        |
|(Jill, Femail, 25) |                |        |
这是toString()方法的结果,而标头是正确的。 我相信编码器有问题,因为如果我使用Encoders.javaSerizlization(T)或Encoders.kryo(T),它会显示

我最担心的是编码器的不正确使用可能会导致错误的SerDe和/或性能损失。 在我能找到的所有Spark Java示例中,我看不到任何特别之处

你能告诉我我做错了什么吗

更新1

以下是我的项目的依赖项:

    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-core_2.10</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-sql_2.10</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-hive_2.10</artifactId>
        <version>1.6.2</version>
    </dependency>

org.apache.spark
),在我的代码中使用Dataset而不是DataFrames(看起来DataFrames不是ApacheSpark的一部分),并使用基于迭代器的flatMap函数从行转换到人

仅与大家分享一下,使用for 1.6.2版的方法对我不起作用,因为它引发了“MyPersonVersion$function1 not Serializable”异常


现在一切正常。

您使用的Spark版本是什么?您提供的flatMap方法不是使用版本2.2.0编译的。所需的返回类型是迭代器。请使用下面的FlatMapFunction,您将获得所需的输出

public static Dataset<Person> transformToPerson(Dataset<Row> rawData) {
    return rawData.flatMap(row -> {
        String[] nameArr = row.getString(0).split(",");
        String[] genArr = row.getString(1).split(",");
        String[] ageArr = row.getString(2).split(",");
        Person person1 = new Person(nameArr[0], genArr[0], ageArr[0]);
        Person person2 = new Person(nameArr[1], genArr[1], ageArr[1]);
        return Arrays.asList(person1, person2).iterator();
    }, Encoders.bean(Person.class));
}

//Call function
Dataset<Person> dataset1 = transformToPerson(dataset);
dataset1.show();
公共静态数据集transformToPerson(数据集rawData){
返回rawData.flatMap(行->{
String[]nameArr=row.getString(0).split(“,”);
String[]genArr=row.getString(1).split(“,”);
String[]ageArr=row.getString(2).split(“,”);
Person person1=新人员(nameArr[0],genArr[0],ageArr[0]);
Person person2=新人员(nameArr[1],genArr[1],ageArr[1]);
返回Arrays.asList(person1,person2.iterator();
},Encoders.bean(Person.class));
}
//调用函数
数据集dataset1=transformToPerson(数据集);
dataset1.show();

abaghel,谢谢!请参阅原始问题中的“更新1”:我添加了更新@Dmitry的详细信息。Spark 1.6.2版本中的bean编码器似乎存在一些问题。请试用Spark 2.0及以上版本。
+-------------------+----------------+--------+
+      name         +       gender   +   age  +
+-------------------+----------------+--------+
|(Jack, Male, 30)   |                |        |
|(Jill, Femail, 25) |                |        |
+------------------+
+        value     +
+------------------+
|(Jack, Male, 30)  |
|(Jill, Femail, 25)|
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-core_2.10</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-sql_2.10</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-hive_2.10</artifactId>
        <version>1.6.2</version>
    </dependency>
public static Dataset<Person> transformToPerson(Dataset<Row> rawData) {
    return rawData.flatMap(row -> {
        String[] nameArr = row.getString(0).split(",");
        String[] genArr = row.getString(1).split(",");
        String[] ageArr = row.getString(2).split(",");
        Person person1 = new Person(nameArr[0], genArr[0], ageArr[0]);
        Person person2 = new Person(nameArr[1], genArr[1], ageArr[1]);
        return Arrays.asList(person1, person2).iterator();
    }, Encoders.bean(Person.class));
}

//Call function
Dataset<Person> dataset1 = transformToPerson(dataset);
dataset1.show();