spark不同结构Dataset合并

1.先将hdfs(或本地)存储的csv文件加载为Dataset

先在本地C盘准备两个csv文件

test.csv

java 复制代码
client_id,behives,del,normal_status,cust_type,no_trd_days
7056,zl,1,hy,个人,2
7057,cf,1,hy,个人,12
7058,hs,2,hy,个人,1200
212121,0,sj,hy,个人,1100
212122,1,yx,hy,个人,100
212123,1,ls,hy,个人,100

test1.csv

java 复制代码
cust_no,code,hight
sw7056,66661,125
es7057,66661,156
wq7058,66661,165

使用spark 加载,并为其创建视图

java 复制代码
Dataset<Row> a = createRealView(session, "file:///C:\\\\test.csv");
Dataset<Row> b = createRealView(session, "file:///C:\\\\test1.csv");
a.createOrReplaceTempView("a");
b.createOrReplaceTempView("b");

由于这两个Dataset的结构和数据量均不一样,若要拼接为一个大的Dataset,可以把每个Dataset多生成一个自动增长编号的列,这里最快的方式是使用每行数据的索引号,则需要转换为RDD操作。

java 复制代码
JavaPairRDD<Long, Row> aNewRDD = a.toJavaRDD().zipWithIndex().mapToPair(tuple -> {
            Long key = tuple._2;
            Row val = tuple._1;
            return new Tuple2<>(key, val);
        });

        JavaPairRDD<Long, Row> bNewRDD = b.toJavaRDD().zipWithIndex().mapToPair(tuple -> {
            Long key = tuple._2;
            Row val = tuple._1;
            return new Tuple2<>(key, val);
        });

原本zipWithIndex()之后的格式为JavaPairRDD<Row, Long> 但是我们需要转换一下结构为JavaPairRDD<Long, Row> 为后续的join操作做准备,因为join关联数据使用的是JavaPairRDD<T,M>中的T字段

java 复制代码
JavaPairRDD<Long, Tuple2<Row, Row>> joinRDD = aNewRDD.join(bNewRDD);
joinRDD.collect().forEach(x -> System.out.println(x));

打印结果为

java 复制代码
(0,([7056,zl,1,hy,个人,2],[sw7056,66661,125]))
(1,([7057,cf,1,hy,个人,12],[es7057,66661,156]))
(2,([7058,hs,2,hy,个人,1200],[wq7058,66661,165]))

那么接下来 需要将Tuple2<Row, Row>中的两个Row合并为一个Row

java 复制代码
JavaRDD<Row> rtRDD = joinRDD.map(tuple -> {
            List<Object> rowContent = new ArrayList<>();
            List<Object> tp1 = JavaConverters.seqAsJavaList(tuple._2._1.toSeq());
            List<Object> tp2 = JavaConverters.seqAsJavaList(tuple._2._2.toSeq());
            rowContent.addAll(tp1);
            rowContent.addAll(tp2);
            Seq<Object> rtSeq = JavaConverters.asScalaIteratorConverter(rowContent.iterator()).asScala().toSeq();
            return Row.fromSeq(rtSeq);
        });

这样就把JavaPairRDD<Long, Tuple2<Row, Row>>转换为JavaRDD<Row>,然后就需要转为Dataset<Row>

由于程序并不知道Dataset的数据结构,则需要建立结果的结构所需的schema

java 复制代码
StructType schema = new StructType(new StructField[]{
                new StructField("client_id", DataTypes.StringType, false, Metadata.empty()),
                new StructField("behives", DataTypes.StringType, false, Metadata.empty()),
                new StructField("del", DataTypes.StringType, false, Metadata.empty()),
                new StructField("normal_status", DataTypes.StringType, false, Metadata.empty()),
                new StructField("cust_type", DataTypes.StringType, false, Metadata.empty()),
                new StructField("no_trd_days", DataTypes.StringType, false, Metadata.empty()),
                new StructField("cust_no", DataTypes.StringType, false, Metadata.empty()),
                new StructField("code", DataTypes.StringType, false, Metadata.empty()),
                new StructField("hight", DataTypes.StringType, false, Metadata.empty())
        });

然后创建出新的Dataset<Row>

java 复制代码
Dataset<Row> dataView = session.createDataFrame(rtRDD, schema);
dataView.show();

最终结果是

java 复制代码
+---------+-------+---+-------------+---------+-----------+-------+-----+-----+
|client_id|behives|del|normal_status|cust_type|no_trd_days|cust_no| code|hight|
+---------+-------+---+-------------+---------+-----------+-------+-----+-----+
|     7056|     zl|  1|           hy|     个人|          2| sw7056|66661|  125|
|     7057|     cf|  1|           hy|     个人|         12| es7057|66661|  156|
|     7058|     hs|  2|           hy|     个人|       1200| wq7058|66661|  165|
+---------+-------+---+-------------+---------+-----------+-------+-----+-----+

完整代码:

java 复制代码
public void createView(SparkSession session, String portraitPath, String prodPath) {
        Dataset<Row> a = createRealView(session, "file:///C:\\\\test.csv");
        Dataset<Row> rowDataset = a.unionAll(a).unionAll(a).orderBy(functions.rand());
        a.createOrReplaceTempView("a");
        Dataset<Row> b = createRealView(session, "file:///C:\\\\test1.csv");
        b.createOrReplaceTempView("b");
        JavaPairRDD<Long, Row> aNewRDD = a.toJavaRDD().zipWithIndex().mapToPair(tuple -> {
            Long key = tuple._2;
            Row val = tuple._1;
            return new Tuple2<>(key, val);
        });
        JavaPairRDD<Long, Row> bNewRDD = b.toJavaRDD().zipWithIndex().mapToPair(tuple -> {
            Long key = tuple._2;
            Row val = tuple._1;
            return new Tuple2<>(key, val);
        });
        JavaPairRDD<Long, Tuple2<Row, Row>> joinRDD = aNewRDD.join(bNewRDD);
        joinRDD.collect().forEach(x -> System.out.println(x));
        StructType schema = new StructType(new StructField[]{
                new StructField("client_id", DataTypes.StringType, false, Metadata.empty()),
                new StructField("behives", DataTypes.StringType, false, Metadata.empty()),
                new StructField("del", DataTypes.StringType, false, Metadata.empty()),
                new StructField("normal_status", DataTypes.StringType, false, Metadata.empty()),
                new StructField("cust_type", DataTypes.StringType, false, Metadata.empty()),
                new StructField("no_trd_days", DataTypes.StringType, false, Metadata.empty()),
                new StructField("cust_no", DataTypes.StringType, false, Metadata.empty()),
                new StructField("code", DataTypes.StringType, false, Metadata.empty()),
                new StructField("hight", DataTypes.StringType, false, Metadata.empty())
        });
        JavaRDD<Row> rtRDD = joinRDD.map(tuple -> {
            List<Object> rowContent = new ArrayList<>();
            List<Object> tp1 = JavaConverters.seqAsJavaList(tuple._2._1.toSeq());
            List<Object> tp2 = JavaConverters.seqAsJavaList(tuple._2._2.toSeq());
            rowContent.addAll(tp1);
            rowContent.addAll(tp2);
            Seq<Object> rtSeq = JavaConverters.asScalaIteratorConverter(rowContent.iterator()).asScala().toSeq();
            return Row.fromSeq(rtSeq);
        });
        Dataset<Row> dataView = session.createDataFrame(rtRDD, schema);
        dataView.show();
    }

    private Dataset<Row> createRealView(SparkSession session, String hdfsPath) {
        Dataset<Row> wideTableDF = null;
        try {
            wideTableDF = session.read().format("csv").option("header", "true").load(hdfsPath);
        } catch (Exception e) {
            System.err.println("未找到有效的宽表数据,查找路径为:" + hdfsPath);
        }
        return wideTableDF;
    }
相关推荐
Json_181790144802 小时前
An In-depth Look into the 1688 Product Details Data API Interface
大数据·json
lzhlizihang3 小时前
【spark的集群模式搭建】Standalone集群模式的搭建(简单明了的安装教程)
spark·standalone模式·spark集群搭建
WX187021128733 小时前
在分布式光伏电站如何进行电能质量的治理?
分布式
Qspace丨轻空间4 小时前
气膜场馆:推动体育文化旅游创新发展的关键力量—轻空间
大数据·人工智能·安全·生活·娱乐
Elastic 中国社区官方博客5 小时前
如何将数据从 AWS S3 导入到 Elastic Cloud - 第 3 部分:Elastic S3 连接器
大数据·elasticsearch·搜索引擎·云计算·全文检索·可用性测试·aws
Aloudata6 小时前
从Apache Atlas到Aloudata BIG,数据血缘解析有何改变?
大数据·apache·数据血缘·主动元数据·数据链路
不能再留遗憾了6 小时前
RabbitMQ 高级特性——消息分发
分布式·rabbitmq·ruby
水豚AI课代表6 小时前
分析报告、调研报告、工作方案等的提示词
大数据·人工智能·学习·chatgpt·aigc
茶馆大橘6 小时前
微服务系列六:分布式事务与seata
分布式·docker·微服务·nacos·seata·springcloud
材料苦逼不会梦到计算机白富美9 小时前
golang分布式缓存项目 Day 1
分布式·缓存·golang