0

我使用 Spark 1.3。

我的数据有 50 多个属性,因此我选择了自定义类。

如何通过名称而不是位置访问自定义类中的字段

这里每次我需要调用一个方法 productElement(0)

我也不应该使用案例类,因此我使用自定义类作为模式。

 class OnlineEvents(gsm_id:String,
          attribution_id:String,
          event_date:String,
          event_timestamp:String,
          event_type:String
          ) extends Product {

  override def productElement(n: Int): Any = n match {
  case 0 => impression_id
  case 1 => attribution_id
  case 2 => event_date
  case 3 => event_timestamp
  case 4 => event_type

  case _ => throw new IndexOutOfBoundsException(n.toString)
 }

  override def productArity: Int = 5

  override def canEqual(that: Any): Boolean = that.isInstanceOf[OnlineEvents]

 }

我的火花代码:

  val onlineRDD = sc.textFile("/user/cloudera/input_files/online_events.txt")

  val schemaRDD = onlineRDD.map(record => {
                                         val arr: Array[String] = record.split(",")
                                          new OnlineEvents(arr(0),arr(1),arr(2),arr(3),arr(4))
})
 val keyvalueRDD =  schemaRDD .map(online => ((online.productElement(0).toString,online.productElement(4).toString),online))

如果我尝试从 OnlineEvents 访问任何字段,那么我需要使用 productElement() 。(即 online.productElement(0) 用于 gsm_id )

我可以直接以 online.gsm_id ... online.event_type 访问该字段,以便我的代码易于阅读

当我将自定义类用于模式时,如何通过字段名称直接访问字段?

4

2 回答 2

1

根据我对你的问题的理解,你需要在functions里面定义一些OnlineEvents来返回类型。所以你的解决方案应该是

class OnlineEvents(gsm_id:String,
                   attribution_id:String,
                   event_date:String,
                   event_timestamp:String,
                   event_type:String
                  ) extends Product {
  def get_gsm_id(): String ={
    gsm_id
  }

  def get_attribution_id(): String ={
    attribution_id
  }

  def get_event_date(): String ={
    event_date
  }

  def get_event_timestamp(): String ={
    event_timestamp
  }

  def get_event_type(): String ={
    event_type
  }

  override def productElement(n: Int): Any = n match {
    case 0 => gsm_id
    case 1 => attribution_id
    case 2 => event_date
    case 3 => event_timestamp
    case 4 => event_type

    case _ => throw new IndexOutOfBoundsException(n.toString)
  }

  override def productArity: Int = 5

  override def canEqual(that: Any): Boolean = that.isInstanceOf[OnlineEvents]

}

并调用如下函数

val keyvalueRDD =  schemaRDD .map(online => ((online.get_gsm_id().toString,online.get_event_type().toString),online))
于 2017-05-14T15:48:52.567 回答
0

我强烈建议每个用例使用一个案例类(它们一起涵盖了所有使用数据的用例)。

单个用例将是一个单个案例类,它可以为您节省大量关于如何维护 50 多个字段的思考。

是的,你会用一个 50 或更多字段的大类来“交易”10 个 5 字段的案例类,但考虑到创建案例类是多么容易,而且它们对你的数据的描述有多好,我认为这是值得的麻烦。

于 2017-05-14T20:15:22.507 回答