Как смоделировать отношения «многие ко многим» с Apache Spark и Sparkube? - PullRequest
0 голосов
/ 06 июня 2018

Давайте рассмотрим набор данных с простым отношением «многие ко многим»: банковские счета, которые могут иметь несколько владельцев.Две таблицы подготовлены и доступны в 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 в виде куба OLAP с Sparkube , чтобы бизнес-пользователи могли создавать свои собственные панели мониторинга в Excel и Tableau.Есть ли способ заставить Sparkube понять отношение «многие ко многим» и раскрыть как правильные агрегаты для каждого владельца, так и правильные итоги.

1 Ответ

0 голосов
/ 12 июня 2018

Sparkube представляет один набор данных как многомерный куб.Таким образом, быстрое решение для этого варианта использования состоит в том, чтобы выставить два куба, один для набора данных «account» и один для набора данных «owner» (объединенный с учетными записями).Затем, когда вы создаете свои панели мониторинга, используйте правильный куб для правильного уровня агрегации.

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-массивы , и это правильный способ моделирования простых отношений «многие ко многим» в одномнабор данных.Объедините две таблицы со 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, агрегаты будут правильными независимо от уровня агрегации и фильтра.

enter image description here

...