本人菜鸟一只,天天写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,但是应该是有某些写法可以避免这个错误,因此我搜索到了如下的东西!
解决:
如下的链接中,有人和我遇到的情况一样!
并且我看到有人给出了回复,大意是:我也遇到了类似的情况,我遵从了以下的链接,一个简单的方案解决了我的错误
链接里是这样的:
https://docs.databricks.com/spark/latest/faq/join-two-dataframes-duplicated-column.html
当我们join的时候,会有一些重复的字段,就可能出现这种问题,因此可以尝试如下的解决方法。
这里我大致说一下:
表A:
用户id | 订单号 |
A123 | qwdqc1223 |
B123 | qwdqc1224 |
表B:
订单号 | 商品号 |
qwdqc1223 | 012,323,3,41 |
qwdqc1224 | 23,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 | 订单号 | 订单号 | 商品号 |
A123 | qwdqc1223 | qwdqc1223 | 012,323,3,41 |
B123 | qwdqc1224 | qwdqc1224 | 23,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 | 商品号 |
qwdqc1223 | A123 | 012,323,3,41 |
qwdqc1224 | B123 | 23,234,45 |
这样就可以避免这个异常了!
好了一篇不是很长的文章,记录了join的api使用方法,大家可以自己尝试下(另外,我发现使用java编写spark的博客确实还是比较少!基本上都是scala)
菜鸟一只,如果有说错的还请大家批评指出!谢谢~
find something more than myself