scala- dataset-如何在两个案例类中使用函数?

时间:2017-07-21 05:57:16

标签: case-class

我有两个数据集并创建两个案例类(我之所以不将ds连接在一起是因为我想在ds B中使用ds A中的键返回第一个匹配记录)

以下是我到目前为止的尝试。如何将该功能映射到两个案例类?非常感谢!我在这里很新。

case class a_class (idA: Int, numA: Int)
case class b_class(idB: Int, numB:Int )
def findNum(a:a_Class, b:b_class): Int = {
     if (a.idA =!=b.idB){
            break
       }else{
       return  b.numB
       }
 }
aTb.createOrReplaceTempView("tableA") 
bTb.createOrReplaceTempView("tableB")
var aDS = sqlContext.table("tableA").as[a_class]
var bDS = sqlContext.table("pview").as[b_class]
 //a_class.map(, => )).show //how do I use findNum function here? 

示例输入:

 +------+---+
 |idA  |numA|
 +------+---+
 |    a |100|
 |    b |200|
 +------+---+

 +------+---+
 |idB   |numB|
 +------+---+
 |a     |500|
 |a     |600|
 +------+---+

因此预期输出为500,因为第一行是表B中的第一个匹配记录

1 个答案:

答案 0 :(得分:2)

您的解决方案位于joingroupByaggregation

首先,您的case class和示例输入数据不匹配,因为ab不能是int类型。所以case classes应该是

case class a_class (idA: String, numA: Int)
case class b_class(idB: String, numB:Int )

使用这些case classes,您可以创建dataSets。出于测试目的,我创建如下

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

val tableA = Seq(
  a_class("a", 100),
  a_class("b", 200)
).toDS

val tableB = Seq(
  b_class("a", 500),
  b_class("a", 600)
).toDS

然后使用以下方法可以实现最终的dataset

tableA.join(tableB, $"idA" === $"idB", "inner") // inner join of two datasets
  .drop("idA", "numA")   //droping columns of tableB
  .groupBy("idB")        //grouping data to get the first of each group
  .agg(first("numB").as("numB"))    //taking the first of each group
  .show(false)

应该给你

+---+----+
|idB|numB|
+---+----+
|a  |600 |
+---+----+

<强>更新

以上结果与您想要的输出不符,这是因为join重新排序tableB

只需执行

即可获得所需的输出
tableB.groupBy("idB")
  .agg(first("numB").as("numB"))
  .show(false)

结果将是row id的每个tableB的第一个+---+----+ |idB|numB| +---+----+ |a |500 | +---+----+

rows

如果您只希望第一个idtableA匹配join,那么您tableAtableA同上,如果您不想要drop的数据,然后您val tempTableB = tableB.groupBy("idB") .agg(first("numB").as("numB")) tableA.join(tempTableB, $"idA" === $"idB", "inner") .drop("idA", "numA") .show(false) 将其作为

row

tableB的{​​{1}}的第一个idtableA的{​​{1}}匹配

+---+----+
|idB|numB|
+---+----+
|a  |500 |
+---+----+