Список / Извлечение разделов HDFS как Map (String, List (String)) из spark - PullRequest
2 голосов
/ 27 июня 2019

Я хотел знать, есть ли какой-нибудь способ использовать информацию метаданных, уже присутствующую в структуре папок hdfs в spark. Например, я использую следующий код для записи данных в hdfs,

val columns = Seq("country","state")
dataframe1.write.partitionBy(columns:_*).mode("overwrite").
save(path)

Создает похожую структуру каталогов,

path/country=xyz/state=1
path/country=xyz/state=2
path/country=xyz/state=3
path/country=abc/state=4

То, что я хочу знать, это использование spark, есть ли способ вывести все разделы и подразделы как Map(String,List(String)) (без загрузки всего файла и с помощью группировки по?), Где ключ - это раздел, а значение - это список всех подразделов в этом разделе.

Вывод приведенного выше примера будет аналогичен следующему

Map(xyz->List(1,2,3),abc->(4))

1 Ответ

3 голосов
/ 28 июня 2019

ваша файловая структура hdfs такая ...

$tree path
path
├── country=abc
│   └── state=4
└── country=xyz
    ├── state=1
    ├── state=2
    ├── state=3
    ├── state=4
    ├── state=5
    └── state=6

вам нужно использовать это для получения полных путей в виде строки ..

val lb = new ListBuffer[String]
  def getAllFiles(path:String, sc: SparkContext):Unit = {
  val conf = sc.hadoopConfiguration
    val fs = FileSystem.get(conf)
    val files: RemoteIterator[LocatedFileStatus] = fs.listLocatedStatus(new Path(path))
    while(files.hasNext) {
      var filepath = files.next.getPath.toString
      //println(filepath)
      lb += (filepath)
      getAllFiles(filepath, sc)
    }
    println(lb)
  }

как только вы получите список всех файлов с полным путем, включая подпапки ... вам нужно написать логику для заполнения на карте. что я оставляю это тебе. Tiy ..

Примечание: у ListBuffer есть группа, по которой карта возврата может быть, вы можете использовать ее

в моем случае я экспериментировал вот так ...

  println( lb.groupBy(_.toString.replaceAll("file:/Users/xxxxxx/path/country=", "")substring(0, 3) ))

Я получил результат как

Map(abc -> ListBuffer(file:/Users/xxxxxx/path/country=abc, file:/Users/xxxxxx/path/country=abc/state=4), xyz -> ListBuffer(file:/Users/xxxxxx/path/country=xyz, file:/Users/xxxxxx/path/country=xyz/state=1, file:/Users/xxxxxx/path/country=xyz/state=6, file:/Users/xxxxxx/path/country=xyz/state=3, file:/Users/xxxxxx/path/country=xyz/state=4, file:/Users/xxxxxx/path/country=xyz/state=5, file:/Users/xxxxxx/path/country=xyz/state=2))

может быть, вы можете использовать эту идею для дальнейшего уточнения до желаемого результата.

...