文章目录
前言
Dataset类,定义了很多算子转换函数。在这其中包含Map,flatMap、take、where、group等操作。
一、转换算子
在Spark中算子执行的对象或是使用到对象,都需要序列化。否则会导致类未找到和空指针异常
Encoders.bean(这里面的类不能是抽象类或是接口,且需实现Serializable接口
1.1 flatMap函数
将当前数据一行转为多行。其中转换的数据类型是自定义的。
public Dataset<String> datasetToFlatMap(Dataset<Row> ds){
return ds.flatMap(new FlatMapFunction<Row, String>() {
@Override
public Iterator<String> call(Row row) throws Exception {
List<String> list = new ArrayList<>();
for(int i = 0 ; i < row.length(); i++){
list.add(row.getString(i));
}
return list.iterator();
}
}, Encoders.STRING());
}
1.2 map函数
public Dataset<String> datasetToMap(Dataset<Row> ds){
return ds.map(new MapFunction<Row, String>() {
@Override
public String call(Row value) throws Exception {
return value.toString();
}
},Encoders.STRING());
}
1.3 select和where
需要注意的是select和where中的字段一定要在Dataset中存在
takeAsList(3) 返回当前数据样例前3条
public List<Row> datasetWhere(Dataset<Row> ds){
return ds.select("v1","v2","v3")
.where("v3 = '"+v3+"'")
.takeAsList(3);
}
1.4 filter(过滤)
过滤掉自己不需要的数据,其中不需要的返回false,需要的返回ture。
public Dataset<String> datasetToFilter(Dataset<Row> ds){
return ds.filter(new FilterFunction<Row>() {
@Override
public boolean call(Row value) throws Exception {
if(value.size() > 0){
return true;
}else{
return false;
}
}
},Encoders.STRING());
}
ds.filter(new FilterFunction<Row>() {
@Override
public boolean call(Row value) throws Exception {
if(value.size() > 0){
return true;
}
return false;
}
});
二、写出到文件
定义输出数据对象。
- 对于已经定义了文件格式的需要注意:在转换过程通过Encoders.bean(OrcHiveEntity.class)算子转换的过程中,字段是按照字段排序的。
- 如果想要按照自己想要的顺序输出可以采用
select("name","age","sex")
来达到排序的目的
/**
* 对象用于Hive保存的ORC文件
*/
public class OrcHiveEntity implements Serializable {
private static final long serialVersionUID = -11540L;
//数据库字段位置: name, age, sex
private String name;
private int age;
private boolean sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
@Override
public String toString() {
return "OrcHiveEntity{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
文件写入模式
public enum SaveMode {
/**
* Append mode means that when saving a DataFrame to a data source, if data/table already exists,
* contents of the DataFrame are expected to be appended to existing data.
* 文件追加写入:文件未存在则创建,文件已存在则追加在已存在文件中
*/
Append,
/**
* Overwrite mode means that when saving a DataFrame to a data source,
* if data/table already exists, existing data is expected to be overwritten by the contents of
* the DataFrame.
* 文件覆盖写入:当文件已存在则覆盖,未存在则创建
*/
Overwrite,
/**
* ErrorIfExists mode means that when saving a DataFrame to a data source, if data already exists,
* an exception is expected to be thrown.
* 文件已存在则抛出异常:文件未存在创建,文件已存在抛出异常
*/
ErrorIfExists,
/**
* Ignore mode means that when saving a DataFrame to a data source, if data already exists,
* the save operation is expected to not save the contents of the DataFrame and to not
* change the existing data.
* 文件以存在则忽略本次操作:文件已存在则忽略本次操作,文件未存在则创建
*/
Ignore
}
1.1 写出格式为ORC
public static void writeOrcFile(Dataset<OrcHiveEntity> dataset, String path){
//通过select来重排字段顺序,达到自己想要的顺序
dataset.select("name","age","sex").write().orc(path);
}
1.2 写出到Parquet
public static void writeOrcFile(Dataset<OrcHiveEntity> dataset, String path){
dataset.write().parquet(path);
}
1.3 写出到Text
需将文件以text文件,对象只能是一个字段的,不能是多个字段的。它是以一个字段为一行的
public static void writeOrcFile(Dataset<String> dataset, String path){
dataset.write().mode(SaveMode.Append).parquet(path);
}