2016-09-28 65 views
5

你好,並提前謝謝。如何使用火花UDF返回複雜類型

我的程序是用java編寫的,我不能移動到scala。

我目前使用下面的行從JSON文件中提取的火花數據幀的工作:

DataFrame dff = sqlContext.read().json("filePath.son");

SQLContext和SparkContext正確initialzied和運行完美。

問題是我正在閱讀的JSON具有嵌套的結構,我想在不更改架構的情況下清理/驗證內部數據。

特別是其中一個數據框的列具有「GenericRowWithSchema」類型。

比方說,我想清理只有名爲「數據」的列。

我想到的解決方案是定義名爲「cleanDataField」的用戶定義函數(UDF),然後在列「data」上運行它。下面的代碼:

UDF1<GenericRowWithSchema,GenericRowWithSchema> cleanDataField = new UDF1<GenericRowWithSchema, GenericRowWithSchema>(){ 

     public GenericRowWithSchema call(GenericRowWithSchema grws){ 

      cleanGenericRowWithSchema(grws); 

      return grws; 

     } 
    }; 

那麼我會在SQLContext註冊功能:

sqlContext.udf().register("cleanDataField", cleanDataField, DataTypes.StringType); 

此後,我會打電話

df.selectExpr("cleanDataField(data)").show(10, false);

爲了看到前10行與乾淨的數據。

最後,問題結果如下:我可以返回複雜的數據(例如自定義類對象)嗎? 如果有可能,我應該怎麼做?我想我不得不改變udf註冊的第三個參數,因爲我沒有返回一個字符串,但是我應該替換它爲什麼?

謝謝

回答

1

比方說,你想構建一個數據類型爲struct<companyid:string,loyaltynum:int,totalprice:int,itemcount:int>

爲此,您可以執行以下操作:

// I am just copying the json string as is but you will need to escape it properly for java. 

DataType dt = DataType.fromJson({"type":"struct","fields":[{"name":"companyid","type":"string","nullable":false,"metadata":{}},{"name":"loyaltynum","type":"integer","nullable":false,"metadata":{}},{"name":"totalprice","type":"integer","nullable":false,"metadata":{}},{"name":"itemcount","type":"integer","nullable":false,"metadata":{}}]}) 

然後,您可以使用這些數據類型作爲返回類型,而註冊您的UDF。