解鎖更多數(shù)據(jù)分析文章歡迎關(guān)注公眾號:數(shù)據(jù)分析EPHS
上一篇中我們介紹了hive中的數(shù)據(jù)類型放刨,其中一類比較重要的類型即集合類型,主要包括struct进统、map、array三種眉菱。那么我們在spark中處理這三種類型呢掉分?本文就來介紹一下俭缓。
1酥郭、數(shù)據(jù)介紹
我們還是先來回顧一下上篇中介紹的數(shù)據(jù):
創(chuàng)建表:
create table if not exists
datatype_test4(
id int,
info struct<name:string,weight:double>,
score array<Int>,
info_map map<string,string>)
row format delimited fields terminated by ','
COLLECTION ITEMS TERMINATED BY ';'
MAP KEYS TERMINATED BY ':';
可以看到,我們定義了三種不同的集合類型字段惜姐,并指定了集合類型的分隔符為";"消返,即struct耘拇,array宇攻,以及map的不同kv之間用";"分割倡勇,同時定義了map的key和value之間用":"分割逞刷。
接下來妻熊,我們創(chuàng)建如下內(nèi)容的txt文件:
1,文文;70,99;96;100,name:文文;country:china
2,毛毛;60,99;92;100,name:毛毛;country:koera
3,超超;65,99;96;100,name:超超;country:japan
倒入hive中并查看:
load data local inpath '/Users/meituan_sxw/Downloads/test4.txt' into table datatype_test4;
select * from datatype_test4;
結(jié)果如下:
2扔役、struct類型
struct類型在spark中對應的類型為org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema,對應的處理代碼如下:
val df = spark.sql(
"""
|select * from
|default.datatype_test4
""".stripMargin)
.map(row=>{
val id = row.getAs[Int]("id")
val info = row.getAs[GenericRowWithSchema]("info")
val name = info.getAs[String]("name")
val weight = info.getAs[Double]("weight")
(id,name,weight)
}).collect().foreach(println)
輸出結(jié)果為:
(1,文文,70.0)
(2,毛毛,60.0)
(3,超超,65.0)
其實一開始我也不知道是什么類型的亿胸,這主要看報錯了,假設(shè)我們按row.getAs[String]("info")去獲取對應的信息婉刀,則會發(fā)現(xiàn)有如下報錯:
所以根據(jù)報錯序仙,順藤摸瓜就可以啦。
3律秃、array類型
對于hive中array類型的數(shù)據(jù)治唤,如果用的是scala語言的話棒动,對應的類型是scala.collection.mutable.WrappedArray肝劲,處理方式如下:
val df = spark.sql(
"""
|select * from
|default.datatype_test4
""".stripMargin)
.map(row=>{
val id = row.getAs[Int]("id")
val score = row.getAs[WrappedArray[Int]]("score")
(id,score(0),score(1),score(2))
}).collect().foreach(println)
輸出結(jié)果為:
(1,99,96,100)
(2,99,92,100)
(3,99,96,100)
4、Map類型
對于hive中map類型的數(shù)據(jù)掷漱,對應的也是Scala中的scala.collection.immutable.Map類型榄檬,處理代碼如下:
val df = spark.sql(
"""
|select * from
|default.datatype_test4
""".stripMargin)
.map(row=>{
val id = row.getAs[Int]("id")
val info = row.getAs[Map[String,String]]("info_map")
val name = info.get("name")
val country = info.get("country")
(id,name,country)
}).collect().foreach(println)
對應的輸出如下:
(1,Some(文文),Some(china))
(2,Some(毛毛),Some(koera))
(3,Some(超超),Some(japan))
看上去有點奇怪,這是因為scala中的get() 方法返回的是一個叫 Option[String] 的類別鹿榜。Option 有兩個子類別锦爵,一個是 Some奥裸,一個是 None,當回傳 Some 的時候樟氢,代表成功地返回了一個 String侠鳄,同時可以通過 get() 這個函式拿到那個 String埠啃,如果返回的是 None伟恶,則代表沒有字符串可以給你。所以博秫,我們正確的寫法如下:
val df = spark.sql(
"""
|select * from
|default.datatype_test4
""".stripMargin)
.map(row=>{
val id = row.getAs[Int]("id")
val info = row.getAs[Map[String,String]]("info_map")
val name = info.get("name").get
val country = info.get("country").get
(id,name,country)
}).collect().foreach(println)
此時才是我們想要的結(jié)果:
(1,文文,china)
(2,毛毛,koera)
(3,超超,japan)
好了,本篇就到這里了台盯!