spark(scala)中对mongodb以及excel的处理和小问题的解决(比如select传入可变参数问题解决)

背景:

采用spark读取mongodb和Excel的数据,由于mongodb是bson类型的数据,需要的字段名比较少且按照层级选取,想到的办法是先把数据全部读成df,然后通过select操作查找需要的字段

出现的问题是:

因为将生成特定字段的df封装成函数,而函数本身是需要传入字段名列表(Seq类型)的,而select操作通过看源码接收的参数类型是

col : scala.Predef.String, cols : scala.Predef.String*

类型的,所以需要处理

相关函数

读取Excel的

def readFromExcel(spark: SparkSession, file: String):DataFrame = {
    spark.sqlContext.read
      .format("com.crealytics.spark.excel")
      .option("path", file)
      .option("useHeader", "true")
      .option("treatEmptyValuesAsNulls", "true")
      .option("inferSchema", "true")
      .option("addColorColumns", "False")
      .option("sheetName", "Sheet1")
      .load()
      .toDF()
  }

其中的file可以放在resource路径下

获取方式为:

val file = this.getClass.getClassLoader.getResource("file.xlsx").getFile

读取mongdb:

def readFromMongo(spark: SparkSession, collection: String, field: Seq[String])(implicit mongoConfig: MongoConfig):DataFrame = {
    spark.read
      .option("uri", mongoConfig.uri)
      .option("collection", collection)
      .format("com.mongodb.spark.sql")
      .load()
      .toDF()
  }

其中关于mongodb的配置操作为

在resource下面新建mongodb.properties文件

mongodb.host=127.0.0.1
mongodb.port=27017
mongodb.db=db

然后新建配置类

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;


public class MongoDBUtil {

    private String host;
    private int port;
    private String db;

    public String getHost() {
        return host;
    }

    public int getPort() {
        return port;
    }

    public String getDb() {
        return db;
    }

    public MongoDBUtil() {
        // 获取配置文件输入流
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("mongodb.properties");
        // 配置类
        Properties properties = new Properties();
        try{
            properties.load(inputStream);
            this.host = properties.getProperty("mongodb.host");
            this.port = Integer.parseInt(properties.getProperty("mongodb.port"));
            this.db = properties.getProperty("mongodb.db");
        }catch (IOException  e){
            e.printStackTrace();
        }
    }
}

在sparksession里面加载mongodb的配置

val mongo = new MongoDBUtil()
val uri = "mongodb://" + mongo.getHost + ":" + mongo.getPort + "/" + mongo.getDb
val config = Map(
   "mongo.uri" -> uri,
   "mongo.db" -> mongo.getDb
)

implicit val mongoConfig: MongoConfig = MongoConfig(config("mongo.uri"), config("mongo.db"))

最后读成df之后,需要选择特定的字段

val field_list = Seq("_id", "data.field_name")

这里表示field_name和data为父子层级,data与_id为同一层级

操作为

val df= readFromMongo(spark, MONGODB_DC_COLLECTION)
val select_df = df.select(field_list.head, field_list.tail: _*)

如果字段名是字符类型的话,比如'a','b'这些

df.select(field_list.map(field.col(_)): _*)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值