Как реализовать "Cross Join" в Spark?

Мы планируем перенести код Apache Pig на новую платформу Spark.

Pig имеет концепцию "Bag/Tuple/Field" и ведет себя аналогично реляционной базе данных. Pig обеспечивает поддержку соединений CROSS/INNER/OUTER.

Для CROSS JOIN мы можем использовать alias = CROSS alias, alias [, alias...] [PARTITION BY parter] [PARALLEL n];

Но когда мы переходим на платформу Spark, я не мог найти аналога в Spark API. У вас есть идеи?

Ответ 1

Это oneRDD.cartesian(anotherRDD).

Ответ 2

Вот рекомендуемая версия для наборов данных Spark 2.x и фреймов данных:

scala> val ds1 = spark.range(10)
ds1: org.apache.spark.sql.Dataset[Long] = [id: bigint]

scala> ds1.cache.count
res1: Long = 10

scala> val ds2 = spark.range(10)
ds2: org.apache.spark.sql.Dataset[Long] = [id: bigint]

scala> ds2.cache.count
res2: Long = 10

scala> val crossDS1DS2 = ds1.crossJoin(ds2)
crossDS1DS2: org.apache.spark.sql.DataFrame = [id: bigint, id: bigint]

scala> crossDS1DS2.count
res3: Long = 100

В качестве альтернативы можно использовать традиционный синтаксис JOIN без условия соединения. Используйте этот параметр конфигурации, чтобы избежать следующей ошибки.

spark.conf.set("spark.sql.crossJoin.enabled", true)

Ошибка, когда эта конфигурация опущена (в частности, используется синтаксис "соединения"):

scala> val crossDS1DS2 = ds1.join(ds2)
crossDS1DS2: org.apache.spark.sql.DataFrame = [id: bigint, id: bigint]

scala> crossDS1DS2.count
org.apache.spark.sql.AnalysisException: Detected cartesian product for INNER join between logical plans
...
Join condition is missing or trivial.
Use the CROSS JOIN syntax to allow cartesian products between these relations.;

Связано: spark.sql.crossJoin.enabled для Spark 2.x