2016-09-29 25 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)方法印刷 ...但它對我來說似乎不明智...