2016-07-18 41 views
1

我有以Avro格式存儲的現有Hive數據。無論出於何種原因通過執行SELECT來讀取這些數據都非常緩慢。我還沒弄明白爲什麼。數據是分區的,我的WHERE子句總是跟在分區列之後。所以我決定通過導航到分區路徑並使用Spark SQLContext直接讀取數據。這工作更快。但是,我遇到的問題是讀取DOUBLE值。 Avro以二進制格式存儲它們。 當我執行在蜂巢以下查詢:如何使用Spark讀取Hive存儲在Avro邏輯格式中的DOUBLE值

select myDoubleValue from myTable; 

我得到了正確的預期值

841.79 
4435.13 
..... 

但下面的代碼星火:

val path="PathToMyPartition" 
    val sqlContext = new SQLContext(sc) 
    val df = sqlContext.read.avro(path) 
    df.select("myDoubleValue").rdd.map(x => x.getAs[Double](0)) 

給了我這個異常

java.lang.ClassCastException : [B cannot be cast to java.lang.Double 

提供模式或將二進制格式的值轉換爲雙精度格式的正確方法是什麼?

+0

請添加架構 –

+0

您的價值已經出現在字符串格式?數據框中數據的格式是什麼? –

+0

當我運行df.schema時,相關字段的格式如下:binary(nullable = true)所以我假設,也是基於我得到的錯誤,它是二元的 –

回答

0

我發現了一個部分解決方案,如何將Avro模式轉換爲Spark SQL StructType。存在由Databricks開發com.databricks.spark.avro.SchemaConverters具有在其toSqlType(avroSchema:架構)轉換阿夫羅邏輯數據類型中的錯誤的方法將其不正確地logicalType

{"name":"MyDecimalField","type":["null",{"type":"bytes","logicalType":"decimal","precision":38,"scale":18}],"doc":"","default":null} 

轉換成

StructField("MyDecimalField",BinaryType,true) 

我在代碼的本地版本修正了這個錯誤,現在它被轉換成

StructField("MyDecimalField",DecimalType(38,18),true) 

現在,下面的代碼讀取的Avro文件和CREA TES一個數據幀:

val avroSchema = new Schema.Parser().parse(QueryProvider.getQueryString(pathSchema)) 
val sqlContext = new SQLContext(sc) 
val df = sqlContext.read.schema(MyAvroSchemaConverter.toSqlType(avroSchema).dataType.asInstanceOf[StructType]).avro(path) 

然而,當我選擇了申請,我希望通過

df.select("MyDecimalField") 

我得到以下異常十進制:

scala.MatchError: [[email protected] (of class [B) 

這是我堅持在這個時間,並會很感激,如果任何人都可以建議下一步做什麼或任何其他工作。

相關問題