Spark-SQL的Java實踐案例(三)
史上最簡單的spark教程
所有代碼示例地址:https://github.com/Mydreamandreality/sparkResearch
(提前聲明:文章由作者:張耀峯 結合自己生產中的使用經驗整理,最終形成簡單易懂的文章,寫作不易,轉載請註明)
(文章參考:Elasticsearch權威指南,Spark快速大數據分析文檔,Elasticsearch官方文檔,實際項目中的應用場景)
(幫到到您請點點關注,文章持續更新中!)
Git主頁 https://github.com/Mydreamandreality
在這裏我們繼續上一章節SparkSQL的案例啊,沒有看上一章節的兄弟萌 點擊這裏哈https://blog.csdn.net/youbitch1/article/details/88852644
這章我們來搞RDD和dataframe的轉換操作
第一種方式
- Spark-SQL支持兩種不同的方式把RDD轉換成dataframe
- 第一種方法是根據RDD對象的具體類型映射,推導出schema,也就是反射
- 這種的映射方式代碼非常簡潔
- 不過前提就是在寫application的時候就需要知道schema
第二種方式
- 通過顯式的程序代碼構造schema,然後將schema應用到RDD上,最後轉換成DataSet
- 雖然這種方法編碼複雜一些,但是這樣我們就可以在不知道DataSet的列名稱的類型的情況下使用,在代碼運行中讀取列和類型
簡單瞭解之後我們直接上代碼,用代碼講解懂得快
第一種方式:反射的方式推導出schema:代碼案例
SparkSession sparkSession = SparkSession.builder().master("local")
.appName("Java Spark SQL")
.getOrCreate();
//定義一個RDD,轉換成DataFrame
JavaRDD<Person> personJavaRDD = sparkSession.read().textFile("URL")
.javaRDD().map(new Function<String, Person>() {
@Override
public Person call(String v1) {
String[] param = v1.split(":");
Person person = new Person();
person.setName(param[0]);
person.setAge(Integer.valueOf(param[1].trim()));
return person;
}
});
//轉換成DataFrame
Dataset<Row> personDataset = sparkSession.createDataFrame(personJavaRDD,Person.class);
代碼模擬debug:(給大家解釋一波代碼)
- 首先我們定義RDD
- 其次map()函數把RDD轉換成Person對象
- 最後把Person的RDD對象轉換成DataFrame
- 就4這麼簡單…
- 轉換成dataframe之後怎麼驗證呢,很簡單:
代碼案例
//創建臨時視圖
personDataset.createOrReplaceTempView("user");
Dataset<Row> result = sparkSession.sql("SELECT * FROM user");
Encoder<String> encoder = Encoders.STRING();
//第一種方式:通過下標獲取value
Dataset<String> dataset = result.map(new MapFunction<Row, String>() {
@Override
public String call(Row value) {
return value.getString(0);
}
},encoder);
dataset.show();
//第二種方式:通過字段獲取value
Dataset<String> fieldValue = result.map(new MapFunction<Row, String>() {
@Override
public String call(Row value) {
return value.getAs("name");
}
},encoder);
fieldValue.show();
- 上面的代碼就是創建一個臨時視圖,執行SQL,第一種通過下標的方式獲取第一條數據,第二種通過字段名稱獲取value
第二種方式:代碼顯式的構造schema:代碼案例
SparkSession sparkSession = SparkSession.builder()
.master("local")
.appName("spark app")
.getOrCreate();
//創建普通的JavaRDD
JavaRDD<String> javaRDD = sparkSession.sparkContext().textFile("URL", 1).toJavaRDD();
//字符串編碼的模式
String schema = "name age";
//根據模式的字符串生成模式
List<StructField> structFieldList = new ArrayList<>();
for (String fieldName : schema.split(" ")) {
StructField structField = DataTypes.createStructField(fieldName, DataTypes.StringType, true);
structFieldList.add(structField);
}
StructType structType = DataTypes.createStructType(structFieldList);
JavaRDD<Row> rowJavaRDD = javaRDD.map(new Function<String, Row>() {
@Override
public Row call(String v1) {
String[] attirbutes = v1.split(",");
return RowFactory.create(attirbutes[0], attirbutes[1].trim());
}
});
//將模式應用於RDD
Dataset<Row> dataset = sparkSession.createDataFrame(rowJavaRDD, structType);
//創建臨時視圖
dataset.createOrReplaceTempView("user");
Dataset<Row> result = sparkSession.sql("select * from user");
result.show();
-
代碼案例解釋:
- 首先我們創建JavaRDD
- 其次創建StructType的schema,與rowJavaRDD結構匹配
- 最後通過sparkSession的createDataFrame把schema應用到rowJavaRDD上形成新的dataframe