Case class scala-dataset-如何在两个case类上使用函数?

Case class scala-dataset-如何在两个case类上使用函数?,case-class,Case Class,我有两个数据集,并创建了两个case类(我之所以不将ds连接在一起,是因为我想返回ds B中的第一个匹配记录以及ds A中的键) 以下是我迄今为止的尝试。如何将该函数映射到两个case类?非常感谢!我是新来的 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.i

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

以下是我迄今为止的尝试。如何将该函数映射到两个case类?非常感谢!我是新来的

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中的第一条匹配记录

您的解决方案在于
join
groupBy
聚合

首先,您的
case类
与示例输入数据不匹配,因为
a
b
不能是
int
类型。因此,
案例类
应该

case class a_class (idA: String, numA: Int)
case class b_class(idB: String, numB:Int )
使用这些
案例类
可以创建
数据集
。出于测试目的,我创建如下内容

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
然后,可以使用以下方法获得最终的
数据集

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
表B
重新排序

你只需这样做就可以得到你想要的输出

tableB.groupBy("idB")
  .agg(first("numB").as("numB"))
  .show(false)
结果将是
表格B

+---+----+
|idB|numB|
+---+----+
|a  |500 |
+---+----+
如果您只需要与
tableA
匹配的
id
的第一行
,那么您将
tableA
合并,如上所述;如果您不需要
tableA
的数据,则将
作为

val tempTableB = tableB.groupBy("idB")
  .agg(first("numB").as("numB"))

tableA.join(tempTableB, $"idA" === $"idB", "inner")
  .drop("idA", "numA")
  .show(false)
输出是
tableB
的第一行
tableA的
id
匹配

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

您可以使用示例输入和预期输出进行更新吗?@user4046073您所说的
是什么意思?我之所以不将ds连接在一起,是因为我想返回ds B中的第一条匹配记录以及ds A中的键
。在Spark中,数据帧/数据集
是分布式的。火花中没有第一个或最后一个。@himanshuiitian“火花中没有第一个或最后一个”@JacekLaskowski没错!我的观点是@user4046073想要使用而不加入
来执行操作,这是不可能的。谢谢你的回答:)这肯定给了我一些想法。但是预期的输出是“a”,“500”,这是数据集B中的第一个匹配记录。为什么在加入后删除B列?请参阅我更新的答案:)我希望我回答并解决了您的问题。您能否发布另一个问题,提供更详细的信息,如如何创建DetriableB并提供更多错误日志?这样我或其他人就可以帮你了。:)表演是一种行为。既然你还没有在诱惑B中应用动作,那就什么也做不了。操作完成时应用转换。因此,错误似乎消失了,但只要您执行操作,错误就会再次出现。因此,如果你想解决这个问题,要么更新这个问题,要么尽可能详细地询问另一个问题。:)如果没有看到规范和程序,就很难得出结论。:)这就是为什么我要你问另一个问题,并提供详细的信息,以便我们能帮助你理解问题的症结所在