2016-09-29 24 views
3

我正在尝试为Java Spark-Sql应用程序编写一些测试。我需要测试一个操作来重新命名列,并且遇到一些困难,比较重命名列的实际值和我的预期值。经过一番实验,我能够写出以下两个测试来演示这个问题:如何在重命名后检查火花列的相等性

首先,作为一个完整性检查,我试过了(df是一个spark sql DataFrame,通过从json文件读取一些示例数据我正在测试):

@Test 
    public void testColumnEquality() throws Exception { 
    Column val1 = df.col("col2"); 
    Column val2 = df.col("col2"); 
    Assert.assertEquals(val1, val2); 
    } 

正如人们所期望的那样通过。然后我尝试这样的:

@Test 
    public void testReanmeColumnEquality() throws Exception { 
    Column val1 = df.col("col2").as("col2"); 
    Column val2 = df.col("col2").as("col2"); 
    Assert.assertEquals(val1, val2); 
    } 

其失败,出现错误java.lang.AssertionError: expected:<col2 AS col2#4L> but was:<col2 AS col2#5L>

在Scala代码周围挖(充分披露 - 我知道很少斯卡拉),它看起来像这样具有与NamedExpression唯一的ID做。

有什么办法可以明智地检查这两列是否代表具有相同别名的相同操作?

(我在火花1.6工作,并会像理想该版本线的解决方案,但如果这是固定的2.0也将是不错的信息。)

谢谢你。

回答

2

我写a blog post有关如何解决此问题:

诀窍是:检查Expression是否有Alias特点:

`column.expr() instanceof Alias` 

如果是这样,解开孩子的表达,并使用该名称提取模式:

​​
+0

你可以在Scala中做到吗? – Wilmerton

0

我做了一些挖掘,它看起来像一个带别名的Column的孩子的信息在实例化新列过程中丢失。也许有一个地方需要查询,但我没有找到它。

所以这不是一个答案,但希望它是有用的或有兴趣的人。

的详细信息

一个Column对象上的as方法的定义指的是name功能(参见Column.scala),其只需要调用定义hereAlias情况类。 Alias(及其child)未公开。它直接给ColumnwithExpr函数,它基于Alias命名的表达式实例化一个新列。

让你无论是比较toString列上直接结果(对丢失其中列来自信息,即该数据帧),或者你实际上解析字符串explain(true)方法印刷 ...但它对我来说似乎不明智...