让我们考虑一个简单的多对多关系的数据集:可以拥有多个所有者的银行账户。这两个表已在Apache Spark中准备并可用。
Owner,Account
John,A01
John,A02
Bob,A02
Bob,A03
Ana,A03
Account,Balance
A01,2000.0
A02,3000.0
A03,5000.0
如果我想查看每个用户的帐户余额,我会在Spark中从"所有者"我加入"帐户"表
Owner,Account,Balance (joined)
John,A01,2000.0
John,A02,3000.0
Bob,A02,3000.0
Bob,A03,5000.0
Ana,A03,5000.0
这样我可以总结余额,每个所有者的总和是正确的。但总和是错误的,因为单个帐户会出现多次。
Owner,Balance
John, 5000.0
Bob, 8000.0
Ana, 5000.0
Total (wrong), 18000.0
如果我想要银行的总金额,我直接在"账户"表
Total (right), 10000.0
现在我想将我的Spark数据集公开为带有Sparkube的OLAP多维数据集,以便业务用户可以在Excel和Tableau中创建自己的仪表板。有没有办法让Sparkube了解多对多关系,并为每个所有者和正确的总计公开正确的聚合。
答案 0 :(得分:0)
Sparkube将一个数据集公开为多维多维数据集。因此,针对此用例的快速解决方案是公开两个多维数据集,一个用于“帐户”数据集,另一个用于“所有者”数据集(用帐户连接)。然后,在制作仪表板时,使用正确的多维数据集进行正确的聚合。
import com.activeviam.sparkube._
new Sparkube()
.fromDataset(account)
.withName("accounts_v1")
.expose()
val owners = owner.join(account, "Account")
new Sparkube()
.fromDataset(owners)
.withName("owners")
.expose()
但这并不好,如果你把它交给最终用户,他们会犯错并显示错误的总数。
由于版本 0.1.6 Sparkube本身支持Spark arrays,这是在单个数据集中建模简单多对多关系的正确方法。将两个表与Spark结合使用,并为每个帐户收集数组中的所有者:
val dataset = owner
.join(account, "Account")
.groupBy("Account")
.agg(collect_list("Owner").as("Owners"))
.join(account, "Account")
dataset.show()
+-------+-----------+-------+
|Account| Owners|Balance|
+-------+-----------+-------+
| A01| [John]| 2000.0|
| A03| [Bob, Ana]| 5000.0|
| A02|[John, Bob]| 3000.0|
+-------+-----------+-------+
new Sparkube()
.fromDataset(dataset)
.withName("accounts_v2")
.expose()
当您从Excel,Tableau或ActiveUI浏览此最新多维数据集时,无论聚合级别如何,聚合都将正确并进行过滤。