【问题标题】:Spark-scala, defining a custom filename conventionSpark-scala,定义自定义文件名约定
【发布时间】:2018-07-10 15:40:13
【问题描述】:

我在一个目录中有文件,它们具有相同的命名约定。它看起来像这样:

id_timestamp_name_someint.txt

例如:

100_20180709010203_FIRST_3432.txt

其中 20180709010203 是 2018 年 07 月 09 日 01 小时 02 分 03 秒。

我这样列出这个目录中的文件名:

def getListOfFiles(dir: String): List[String] = {
  val file = new File(dir)
  file.listFiles.filter(_.isFile).sortBy(_.lastModified).map(_.getName).toList 
}

现在我需要在 spark-scala 上定义命名约定,以便 spark 可以识别哪个位置是 id、时间戳和名称。因为我想将文件与它们的 id 进行比较,然后再与时间戳进行比较。有人知道怎么做吗?

【问题讨论】:

  • 你能添加更多关于你想要达到的目标的信息吗(不确定你在这里比较的意思)?您想根据 id/timestamp/name 将不同的文件组加载到 spark 中吗?
  • 我想比较 ID。如果它们相同,那么我想比较时间戳。如果日期比之前的“晚” - 这意味着我必须比较内容,如果有新记录,我必须添加这些,以便更新表格。但首先我必须定义命名约定,所以是通用的。 (第一个位置是ID,第二个时间戳等)
  • 听起来您可以在“_”上拆分,然后使用案例类将文件名分隔为 id、时间戳等。这会有帮助吗?
  • 这也是我目前所知道的。我无法构建我的代码。拆分是明确的..然后我不得不说第一块是ID,第二块是时间戳等等。

标签: scala apache-spark


【解决方案1】:

要对目录中包含的某些文件的名称定义一些逻辑,您可以使用wholeTextFiles,它返回一个将文件名与其内容相关联的元组的 RDD。

在您的情况下,您可以执行以下操作:

case class FileName(id : Int, ts : String, name : String, value : Int)
val rdd : RDD[(FileName, String)] = sc
  .wholeTextFiles("hdfs:///tmp/files")
  .map{ case(path, content) => 
      path.replaceAll(".txt$", "").split("/").last.split("_") -> content }
  /* the logic here is to first remove ".txt", then get rid of the path
     and finally splitting on '_' to separate your 4 fields. */
  .map{ case (Array(id, ts, name, value), content) => 
      FileName(id.toInt, ts, name, value.toInt) -> content}

然后您可以在rdd 上应用您喜欢的任何逻辑,例如使用reduceByKey 来保留您感兴趣的记录。

例如,假设对于每个 id 和 name,您希望保留具有最新时间戳的记录。你可以这样做:

rdd
    .map{ case(fn, content) => (fn.id, fn.name) -> (fn.ts, fn.value, content) }
    .reduceByKey((a, b) => if(a._1 >= b._1) a else b)

【讨论】:

  • 你能给我一些关于reduceByKey的例子吗,因为我这实际上是我的问题?我无法构建我的 coce 来实现这一目标。
  • 我添加了一个使用 reduceByKey 的示例。如果这对您没有帮助,请尝试编辑您的问题以添加有关您要实现的目标的更多详细信息。
  • case class FileName(id : Int, ts : String, name : String, value : Int) 这是一个很好的提示!我现在只想说,我的文件名的第一部分(直到第一个 _)是 id,第二部分是时间戳,第三部分是名称。所以在这个例子中:100_20180709010203_FIRST_3432.txt spark应该认识到100是id(直到第一个_)它们是时间戳,然后是名称,然后是值。所以使用 getListOfFiles - 我已经可以列出目录中的所有文件名,我现在只想按照上面的解释定义这些。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-10
  • 2011-04-03
  • 2013-07-19
  • 2011-04-26
  • 1970-01-01
相关资源
最近更新 更多