Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spark SQL Java无法从元组转换为行和数据帧_Java_Apache Spark_Apache Spark Sql - Fatal编程技术网

Spark SQL Java无法从元组转换为行和数据帧

Spark SQL Java无法从元组转换为行和数据帧,java,apache-spark,apache-spark-sql,Java,Apache Spark,Apache Spark Sql,我正在尝试从JavaRDD对象创建Dataset对象 我遵循以下步骤 将Java转换为JavaRDD 将sqlContext的toDataset()函数与模式一起使用以转换为数据集 但是,在第一步中,我无法在代码中使用类似scala的Row.fromTuple()函数。 在第二步中,我无法使用rowTag进行转换 下面是运行时错误 Error: java: cannot find symbol symbol: method fromTuple(scala.Tuple2<org.ap

我正在尝试从
JavaRDD
对象创建
Dataset
对象

我遵循以下步骤

  • Java
    转换为
    JavaRDD
  • sqlContext
    toDataset()
    函数与模式一起使用以转换为数据集
  • 但是,在第一步中,我无法在代码中使用类似scala的
    Row.fromTuple()
    函数。 在第二步中,我无法使用rowTag进行转换

    下面是运行时错误

    Error: java: cannot find symbol
      symbol:   method fromTuple(scala.Tuple2<org.apache.spark.sql.Row,org.apache.spark.sql.Row>)
      location: interface org.apache.spark.sql.Row
    
    错误:java:找不到符号
    符号:方法fromTuple(scala.Tuple2)
    位置:interface org.apache.spark.sql.Row
    
    我试着像下面这样转换

    ClassTag<Row> rowTag = scala.reflect.ClassTag$.MODULE$.apply(Row.class);
    
    private Dataset<Row> joinResults(SparkSession session, RDD<Tuple2<Row, Row>> resultRDD) {
        JavaRDD<Tuple2<Row, Row>> results = resultRDD.toJavaRDD();
    
        JavaRDD<Row> ds = results.map(new Function<Tuple2<Row, Row>, Row>() {
            @Override
            public Row call(Tuple2<Row, Row> rowRowTuple2) throws Exception {
                return Row.fromTuple(rowRowTuple2); // run time error
            }
        });
        
        return session.sqlContext().createDataset(ds, rowTag); //gives error
    }
    
    ClassTag rowTag=scala.reflect.ClassTag$.MODULE$.apply(Row.class);
    专用数据集joinResults(SparkSession会话,RDD resultRDD){
    JavaRDD results=resultRDD.toJavaRDD();
    javardds=results.map(新函数(){
    @凌驾
    公用行调用(Tuple2 RowTuple2)引发异常{
    返回Row.fromTuple(rowtuple2);//运行时错误
    }
    });
    return session.sqlContext().createDataset(ds,rowTag);//给出错误信息
    }
    
    任何帮助都将不胜感激。我正在使用,这将返回RDD,因此我没有直接在数据集上执行操作的选项。我不想每次都创建模式/编码器,因为这会限制链接函数的使用。我使用的是Scala 2.11和Spark 2.4.3 libs

  • .createDataset()
    接受
    RDD
    而不是
    JavaRDD。
    JavaRDD: 您需要使用
    ds.rdd()

  • 您需要创建并传递
    org.apache.spark.sql.catalyst.encoders.rowcoder

  • 不要通过
    row.fromTuple(rowtuple2)
    创建一行行(即每个元素都是一行的行)。单行应包含基元类型或嵌套结构()


  • 也许这是有用的-

    Tuple2
    ->
    Dataset
    StructType架构=新的StructType()
    .add(新的StructField(“id”,DataTypes.IntegerType,true,Metadata.empty())
    .add(new StructField(“name”,DataTypes.StringType,true,Metadata.empty());
    JavaRDD tuple2JavaRDD=新的JavaSparkContext(spark.sparkContext())
    .并行化(
    Arrays.asList(Tuple2.apply(RowFactory.create(1),RowFactory.create(“a”)),
    Tuple2.apply(RowFactory.create(2),RowFactory.create(“b”))
    );
    JavaRDD rowJavaRDD1=tuple2JavaRDD.map(t->Row$.MODULE$.merge(
    toScalaSeq(数组.asList(t.'u 1,t.'u 2))
    ));
    Dataset df1=spark.createDataFrame(rowJavaRDD1,模式);
    df1.显示(假);
    df1.printSchema();
    /**
    * +---+----+
    *| id |名称|
    * +---+----+
    *| 1 | a|
    *| 2 | b|
    * +---+----+
    *
    *根
    *|--id:integer(nullable=true)
    *|--name:string(nullable=true)
    */
    
    Tuple2
    ->
    Dataset
    
    JavaRDD resultRDD=新的JavaSparkContext(spark.sparkContext())
    .parallelize(Arrays.asList(Tuple2.apply(1,“a”),Tuple2.apply(2,“b”));
    JavaRDD rowJavaRDD=resultRDD.map(Row$.MODULE$::fromTuple);
    Dataset dataFrame=spark.createDataFrame(rowJavaRDD,模式);
    dataFrame.show(false);
    dataFrame.printSchema();
    /**
    * +---+----+
    *| id |名称|
    * +---+----+
    *| 1 | a|
    *| 2 | b|
    * +---+----+
    *
    *根
    *|--id:integer(nullable=true)
    *|--name:string(nullable=true)
    */
    
    大多数spark API都在scala seq上工作,最好使用下面的实用工具来转换java List->scala序列

    Buffer-toScalaSeq(列表){
    返回JavaConversions.asScalaBuffer(列表);
    }
    
    谢谢@Yoshi。您还可以告诉我们如何使用java中的
    Row.fromTuple
    Row.merge
    吗?非常有效。!