【spark】异常:org.apache.spark.sql.AnalysisException: resolved attribute(s)

本人菜鸟一只,天天写bug,今天又来记录一个解决了的bug!

业务逻辑:

1、从一张行为表中,抽取有特点行为的用户

2、将这部分用户id拿到之后保存

3、然后再将这部分用户id关联回行为表,获得这部分用户的所有行为

 具体代码我就不贴出来了,应该比较简单吧,就是读取行为表,过滤特定的行为,然后将这部分数据去重就得到特定行为的用户,最后把这些用户关联回行为表,就拿到了这部分特定用户的行为

报错如下:

org.apache.spark.sql.AnalysisException: resolved attribute(s) 字段1#13,字段2#17 missi
ng from 字段1#245,字段2#249 in operator !Project [字段1#13, 字段2#17];;
......这里一大堆执行计划

	at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$class.failAnalysis(CheckAnalysis.scala:39)
	at org.apache.spark.sql.catalyst.analysis.Analyzer.failAnalysis(Analyzer.scala:91)
	at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$$anonfun$checkAnalysis$1.apply(CheckAnalysis.scala:347)
	at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$$anonfun$checkAnalysis$1.apply(CheckAnalysis.scala:78)
	at org.apache.spark.sql.catalyst.trees.TreeNode.foreachUp(TreeNode.scala:127)
	at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$class.checkAnalysis(CheckAnalysis.scala:78)
	at org.apache.spark.sql.catalyst.analysis.Analyzer.checkAnalysis(Analyzer.scala:91)
	at org.apache.spark.sql.execution.QueryExecution.assertAnalyzed(QueryExecution.scala:52)
	at org.apache.spark.sql.Dataset$.ofRows(Dataset.scala:67)
	at org.apache.spark.sql.Dataset.org$apache$spark$sql$Dataset$$withPlan(Dataset.scala:2884)
	at org.apache.spark.sql.Dataset.select(Dataset.scala:1150)
	at org.apache.spark.sql.Dataset.select(Dataset.scala:1150)
	at ...run方法异常
	at ...main方法异常
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:775)
	at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:180)
	at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:205)
	at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:119)
	at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

看起来是join的时候,有些字段查不到,我觉得这个像是spark的bug,但是应该是有某些写法可以避免这个错误,因此我搜索到了如下的东西!

解决:

如下的链接中,有人和我遇到的情况一样!

http://apache-spark-user-list.1001560.n3.nabble.com/org-apache-spark-sql-AnalysisException-resolved-attribute-s-code-906-missing-from-code-1992-td28555.html

并且我看到有人给出了回复,大意是:我也遇到了类似的情况,我遵从了以下的链接,一个简单的方案解决了我的错误

链接里是这样的:

https://docs.databricks.com/spark/latest/faq/join-two-dataframes-duplicated-column.html

当我们join的时候,会有一些重复的字段,就可能出现这种问题,因此可以尝试如下的解决方法。

这里我大致说一下:

表A:

用户id订单号
A123qwdqc1223
B123qwdqc1224

表B:

订单号商品号
qwdqc1223012,323,3,41
qwdqc122423,234,45

错解:

join的时候(代码是java版本写的spark),使用

Dataset<Row> biaoA = spark.table(表A);
Dataset<Row> biaoB = spark.table(表B);

Dataset<Row> biaoC = biaoA.join(biaoB,biaoA.col(订单号).eqaulsTo(biaoB.col(订单号)));

得到表C:

用户id订单号订单号商品号
A123qwdqc1223qwdqc1223012,323,3,41
B123qwdqc1224qwdqc122423,234,45

会有两列订单号,看起来是一样的,实际上在执行计划里面是订单号#13,订单号#241这么标识来区分的,当然我们这个报错就是因为区分出了问题才会出现,所以我们需要用文档中给出的方式来查数据,如下:

正解:

其实主要就是注意多个关联字段如何写!

//java版本:
Dataset<Row> biaoA = spark.table(表A);
Dataset<Row> biaoB = spark.table(表B);

Dataset<Row> biaoC = biaoA.join(biaoB,"订单号");

//如果有多个字段关联
List<String> tmpList = new ArrayList<>();
tmpList.add("订单号");
tmpList.add("日期");
Seq<String> tmpSeq = JavaConverters.asScalaIteratorConverter(tmpList.iterator()).asScala().toSeq();
Dataset<Row> biaoC = biaoA.join(biaoB,tmpSeq);


//scala版本:
val c = biaoA.join(biaoB , "订单号")

val c = biaoA.join(biaoB , Seq("订单号"))


//python版本:
c = biaoA.join(biaoB , ["订单号","日期"])

c = biaoA.join(biaoB , "订单号")

 如果使用上面的api得到的数据就会如下:

表C:订单号只会剩下一列!

订单号用户id商品号
qwdqc1223A123012,323,3,41
qwdqc1224B12323,234,45

 

这样就可以避免这个异常了!

好了一篇不是很长的文章,记录了join的api使用方法,大家可以自己尝试下(另外,我发现使用java编写spark的博客确实还是比较少!基本上都是scala)

菜鸟一只,如果有说错的还请大家批评指出!谢谢~

find something more than myself

 

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值