为啥 Spark Dataset.select 替换列值

Posted

技术标签:

【中文标题】为啥 Spark Dataset.select 替换列值【英文标题】:Why Spark Dataset.select replacing the column values为什么 Spark Dataset.select 替换列值 【发布时间】:2020-01-15 20:02:32 【问题描述】:
Dataset<Row> ds = .....
ds = ds.select("cola", "colb");
ds.show();

DS 已正确加载。 DS 包含多个列。我想选择“cola”和“colb”列。这些列确实存在,否则上面的代码会抛出错误Caused by: org.apache.spark.sql.AnalysisException: cannot resolve colA given input columns。我的问题是它用列名替换值。如何保留原始值?

expected 

cola | colb
1       2
3       4

我得到了什么

cola | colb
cola   colb 
cola   colb

【问题讨论】:

看起来您正在选择文字。您必须告诉 spark 您正在选择列。试试ds.select($"cola",$"colb") 这看起来像是上游 JDBC 的问题。 @Andrew 我正在使用 Java 并且 $ 无法解析符号。我确实导入了 org.apache.spark.sql._ 。 user10938362 你是对的。如果我使用虚拟数据源这样做,它就可以工作。问题是那个特定的数据源。解决方法是什么? 试试col("cola")。我认为这应该可行。 导入静态 org.apache.spark.sql.functions.col; ds = ds.select(col("cola"), col("colb"));结果相同 【参考方案1】:

当您从 DB 将数据加载到 dataSet 时,切勿相信数据已正确加载,直到您可以看到实际数据。

对于这种情况,我可以看到 ds.printSchema ,我可以看到 ds.count().show() 但是当我在做 ds.select("cola", "colb") 时,它没有显示正确的数据。

现在进行一些调查发现我不应该在从 memSql 加载时使用 JDBC

我正在使用以下 这是错误的 。它可以加载模式,计数但不能加载实际数据。

 Dataset<Row> ds= spark.read()
                .format("jdbc")
                .option("user", getDbUser(true))
                .option("password", getDbPass(true))
                .option("url", h2RawPositions)
                .option("dbtable", h2PositionTableName)
                .load();

相反,我使用了 com.memsql.spark.connector (Source),它有效。

Dataset<Row> gsProducts = spark.read()
                .format("com.memsql.spark.connector")
                .option("url", memsqlConnection)
                .option("dbtable", mamsqlTableName) 
                .option("query", "select blah, blah frm memSqlTableName")
                .load();

【讨论】:

以上是关于为啥 Spark Dataset.select 替换列值的主要内容,如果未能解决你的问题,请参考以下文章

spark dataframe 类型转换

JAVA spark数据集中的GroupBy和聚合函数

在 Spark 中将可选参数建模为 UDF 的最佳方法是啥?

如何从Spark中的聚合结构对象中删除“ col1”别名?

Spark学习笔记——构建分类模型

有spark为啥还要hive