2016-09-28 1 views
5

zurückgegeben werden Hallo und vielen Dank im Voraus.Wie komplexe Typen mit Funken UDFs

Mein Programm ist in Java geschrieben und ich kann nicht auf scala verschieben.

Zur Zeit arbeite ich mit einem Funken Datenrahmen aus einer JSON-Datei extrahiert mit der folgenden Zeile:

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

SqlContext und SparkContext richtig initialzied und läuft perfekt.

Das Problem ist der JSON ich habe von verschachtelten Strukturen gelesen, und ich möchte die inneren Daten reinigen/verifizieren, ohne das Schema zu ändern.

Eine der Spalten des Datenrahmens hat insbesondere den Typ "GenericRowWithSchema".

Nehmen wir an, ich möchte nur die Spalte "Daten" reinigen.

Die Lösung, die mir in den Sinn kam, war eine benutzerdefinierte Funktion (UDF) namens "cleanDataField" definieren und dann über die Spalte "Daten" laufen. Hier ist der Code:

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

     public GenericRowWithSchema call(GenericRowWithSchema grws){ 

      cleanGenericRowWithSchema(grws); 

      return grws; 

     } 
    }; 

Dann würde ich die Funktion im SqlContext registrieren:

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

Und danach würde ich

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

Um rufen Sie die ersten 10 zu sehen Zeilen mit den sauberen Daten.

Am Ende ergibt sich die Frage: Kann ich komplexe Daten (wie ein benutzerdefiniertes Klassenobjekt) zurückgeben? Und wenn es möglich ist, wie soll ich es tun? Ich denke, ich muss den 3. Parameter der udf-Registrierung ändern, weil ich keine Zeichenfolge zurückgebe, aber wofür soll ich sie ersetzen?

Danke

Antwort

1

Angenommen, Sie für diese einen Datentyp als struct<companyid:string,loyaltynum:int,totalprice:int,itemcount:int>

bauen möchten, können Sie wie folgt vorgehen:

// 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":{}}]}) 

Sie können dann diesen Datentyp als Rückgabetyp während verwenden Registrierung Ihrer UDF.

Verwandte Themen