spark要写入分区的数据帧

时间:2017-05-29 04:59:05

标签: scala apache-spark

我是新来的火花和斯卡拉。我想读一个包含json文件的目录。该文件具有名为" EVENT_NAME"的属性它可以有20个不同的值。我需要根据属性值分隔事件。即EVENT_NAME = event_A事件。将这些写在hive外部表结构中,如:/ apps / hive / warehouse / db / event_A / dt = date / hour = hr

这里我有20个不同的表用于所有事件类型,与每个事件相关的数据应该转到相应的表。 我设法写了一些代码,但需要帮助才能正确编写我的数据。

{
import org.apache.spark.sql._
import sqlContext._

val path = "/source/data/path"
val trafficRep = sc.textFile(path)

val trafficRepDf = sqlContext.read.json(trafficRep)
trafficRepDf.registerTempTable("trafficRepDf")

trafficRepDf.write.partitionBy("EVENT_NAME").save("/apps/hive/warehouse/db/sample")
}

最后一行创建分区输出但不是我需要它的确切方式。请建议我如何才能正确使用它或任何其他代码。

4 个答案:

答案 0 :(得分:2)

我假设您的意思是将数据保存到单独的目录中,而不使用Spark / Hive的{column}={value}格式。

您将无法使用Spark的partitionBy,因为Spark分区会强制您使用该格式。

相反,您必须将DataFrame分解为其组件分区,并逐个保存,如下所示:

{
  import org.apache.spark.sql._
  import sqlContext._

  val path = "/source/data/path"
  val trafficRep = sc.textFile(path)

  val trafficRepDf = sqlContext.read.json(trafficRep)
  val eventNames = trafficRepDf.select($"EVENT_NAME").distinct().collect() // Or if you already know what all 20 values are, just hardcode them.
  for (eventName <- eventNames) {
    val trafficRepByEventDf = trafficRepDef.where($"EVENT_NAME" === eventName)
    trafficRepByEventDf.write.save(s"/apps/hive/warehouse/db/sample/${eventName}")
  }
}

答案 1 :(得分:1)

您可以将包含日期和小时的列添加到数据框中。

import org.apache.spark.sql._
import sqlContext._

val path = "/source/data/path"
val trafficRep = sc.textFile(path)

val trafficRepDf = sqlContext.read.json(trafficRep)
trafficRepDf.withColumn("dt", lit("dtValue")).withColumn("hour", lit("hourValue"))

trafficRepDf.write.partitionBy("EVENT_NAME","dt","hour").save("/apps/hive/warehouse/db/sample")

答案 2 :(得分:0)

我假设你想要一个像/apps/hive/warehouse/db/EVENT_NAME=xx/dt=yy/hour=zz这样的表结构,然后你需要按EVENT_NAMEdthour进行分区,所以试试这个:

trafficRepDf.write.partitionBy("EVENT_NAME","dt","hour").save("/apps/hive/warehouse/db/sample")

答案 3 :(得分:0)