如何从spark

时间:2018-04-18 06:56:38

标签: apache-spark spark-dataframe

我只需要从匹配特定模式的目录中加载那些文件来运行我的spark作业。 例如,我在目录中有5k文本文件,其命名模式低于命名模式

Fundamental.FinancialLineItem.FinancialLineItem.Japan.BAL.1.2018-04-12-0542.Full
Fundamental.FinancialLineItem.FinancialLineItem.Japan.BUS.1.2018-04-12-0542.Full
Fundamental.FinancialLineItem.FinancialLineItem.SelfSourcedPrivate.SHE.1.2018-04-12-0542.Full
Fundamental.FinancialLineItem.FinancialLineItem.SelfSourcedPublic.PEN.1.2018-04-12-0542.Full

Fundamental.FinancialLineItem.Segments.Japan.1.2018-04-12-0542.Full
Fundamental.FinancialPeriod.FinancialPeriod.Japan.2018.1.2018-04-16-0348.Full
Fundamental.FinancialPeriod.Interim2Annual.Japan.1970.1.2018-04-13-0732.Full

像这样我在目录中有5k文本文件。 在我的spark作业中,如果我们用FinancialLineItem分割文件的名称,我必须从左到右加载只有"."在第三个位置的文件。 因此,只有前4个文件才会被加载。

我无论如何只能加载那个文件。如果我在sc.TextFile()中提供了dir名称,那么将加载完整目录,这将占用大量空间。 目前我正在加载像这样的文件

//Loading main file
val rdd = sc.textFile(mainFileURL)
//val rdd =sc.wholeTextFiles(mainFileURL).filter(x => x._1.contains("FinancialLineItem")).flatMap(_._2.split("\n"))
//val rdd =sc.wholeTextFiles(mainFileURL).filter(x => Try(x._1.split("/").last.split("\\.")(2)).getOrElse("").equals("FinancialLineItem")).flatMap(_._2.split("\n"))
val header = rdd.filter(_.contains("LineItem.organizationId")).map(line => line.split("\\|\\^\\|")).first()
val schema = StructType(header.map(cols => StructField(cols.replace(".", "_"), StringType)).toSeq)
val data = sqlContext.createDataFrame(rdd.filter(!_.contains("LineItem.organizationId")).map(line => Row.fromSeq(line.split("\\|\\^\\|").toSeq)), schema)
val get_cus_val = sqlContext.udf.register("get_cus_val", (filePath: String) => filePath.split("\\.")(3))
val df1resultFinal = data.withColumn("DataPartition", get_cus_val(input_file_name))
val dataMain = df1resultFinal.withColumn("TimeStamp", lit(null: String))

mainFileURL是我的目录名。

2 个答案:

答案 0 :(得分:1)

您可以使用sc.wholeTextFiles过滤掉您的文件名。使用下面的代码获得所需的结果。

sc.wholeTextFiles(mainFileURL).filter(x => Try(x._1.split("/").last.split("\\.")(2)).getOrElse("").equals("FinancialLineItem")).flatMap(_._2.split("\n"))

答案 1 :(得分:0)

使用glob模式定义输入。使用Dataset

spark.read.text(
  s"${mainFileURL}/Fundamental.FinancialLineItem.FinancialLineItem*"
)

使用RDD

spark.sparkContext.textFile(
  s"${mainFileURL}/Fundamental.FinancialLineItem.FinancialLineItem*"
)

这样您只会扫描文件系统,并避免加载整个数据(与wholeTextFiles一样)。