JAVA中Spark迁移数据-hive到mongoDB(没数据添加有数据则更新)

最近做的业务是在java层面对hive数据进行迁移到mongo。
在迁移数据的时候需要判断从hive来的数据在mongo是否存在。
如果存在则对已有的数据更新(根据某一字段更新),没有数据则直接添加。
我现在基于java分享相关的方法,拿走即用的代码段。

1、处理RDD

JavaRDD<Row> rdd = dataset.toJavaRDD();
        JavaRDD<ReplaceOneModel<Document>> rddUpsert = rdd.map(new Function<Row, ReplaceOneModel<Document>>() {
            @Override
            public ReplaceOneModel<Document> call(Row v1) {
                Document doc = new Document();
                StructField[] str = v1.schema().fields();
                Object[] values = ((GenericRowWithSchema) v1).values();
                for (int i = 0; i < str.length; i++) {
                    String field = str[i].name();
                    Object data = values[i];
                    doc.put(field, data);
                }
                //fieldName为过滤条件;value为doc字段
                return new ReplaceOneModel<Document>(Filters.eq("flag", doc.get("flag")), doc, new ReplaceOptions().upsert(true));
            }
        });

这部分主要将我们需要更新的数据基于更新字段 进行处理。

其中 Document 很重要,它需要携带我们需要处理的数据。最后根据更新字段走下面的更新逻辑。

2、处理需要更新逻辑

//根据自己情况定义 writeConfig
        WriteConfig writeConfig = WriteConfig.create("数据库名", "mongo指定集合", "数据库url", 5, WriteConcern.ACKNOWLEDGED);

        DefaultMongoClientFactory factory = new DefaultMongoClientFactory("mongo的url", Option.apply(99));
        MongoConnector mongoConnector = new MongoConnector(factory);
        ClassTag<Document> tag = ClassManifestFactory.classType(Document.class);
        rddUpsert.foreachPartition(iterm -> {
            mongoConnector.withCollectionDo(writeConfig, collection -> {
                iterm.forEachRemaining(batch -> {
                 //batc为每一条文档
                    collection.bulkWrite(Collections.singletonList(batch));
                });
                return null;
            }, tag);
        });

3、完整示例代码 

JavaRDD<Row> rdd = dataset.toJavaRDD();
        JavaRDD<ReplaceOneModel<Document>> rddUpsert = rdd.map(new Function<Row, ReplaceOneModel<Document>>() {
            @Override
            public ReplaceOneModel<Document> call(Row v1) {
                Document doc = new Document();
                StructField[] str = v1.schema().fields();
                Object[] values = ((GenericRowWithSchema) v1).values();
                for (int i = 0; i < str.length; i++) {
                    String field = str[i].name();
                    Object data = values[i];
                    doc.put(field, data);
                }
                //fieldName为过滤条件;value为doc字段
                return new ReplaceOneModel<Document>(Filters.eq("flag", doc.get("flag")), doc, new ReplaceOptions().upsert(true));
            }
        });

        //根据自己情况定义 writeConfig
        WriteConfig writeConfig = WriteConfig.create("数据库名", "mongo指定集合", "数据库url", 5, WriteConcern.ACKNOWLEDGED);

        DefaultMongoClientFactory factory = new DefaultMongoClientFactory("mongo的url", Option.apply(99));
        MongoConnector mongoConnector = new MongoConnector(factory);
        ClassTag<Document> tag = ClassManifestFactory.classType(Document.class);
        rddUpsert.foreachPartition(iterm -> {
            mongoConnector.withCollectionDo(writeConfig, collection -> {
                iterm.forEachRemaining(batch -> {
                    //batc为每一条文档
                    collection.bulkWrite(Collections.singletonList(batch));
                });
                return null;
            }, tag);
        });

 

本部分将处理完的RDD数据传下来,连接对应的数据库。将传下来的RDD进行处理更新存储。

最后就能达到我们的需求。mongo里面没有数据的时候走添加操作,有数据的时候走更新操作。

ps:可能因为框架原因,可能出现序列化问题。出现的时候,全局进行序列化即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一枝风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值