Apache spark 在火花上或火花中处理连接

Apache spark 在火花上或火花中处理连接,apache-spark,join,apache-spark-sql,Apache Spark,Join,Apache Spark Sql,我有这样一个数据框: +---+---+---+---+---+ |AId| A1| A2| A3| A4| +---+---+---+---+---+ | 1| *| a| b| c| | 2| *| *| b| c| | 3| c| a| b| c| | 4| *| *| *| c| | 5| *| *| *| *| +---+---+---+---+---+ 我想参加以下活动: +---+---+---+---+---+----+ |BI

我有这样一个数据框:

+---+---+---+---+---+
|AId| A1| A2| A3| A4|
+---+---+---+---+---+
|  1|  *|  a|  b|  c|
|  2|  *|  *|  b|  c|
|  3|  c|  a|  b|  c|
|  4|  *|  *|  *|  c|
|  5|  *|  *|  *|  *|
+---+---+---+---+---+
我想参加以下活动:

+---+---+---+---+---+----+
|BId| B1| B2| B3| B4|Code|
+---+---+---+---+---+----+
|  1|  c|  a|  b|  c|  AO|
|  2|  b|  a|  b|  c|  AS|
|  3|  b|  b|  b|  c|  AT|
|  4|  a|  d|  d|  c|  BO|
|  5|  d|  a|  c|  b|  BS|
|  6|  a|  b|  b|  c|  BT|
|  7|  d|  d|  d|  c|  CO|
|  8|  d|  d|  d|  d|  CS|
+---+---+---+---+---+----+
将ID与规则匹配。但是,*是一个通配符。它可以匹配任何东西。在上面的示例中,AId==1将匹配BId 1和2,AId==3将仅匹配BId 1,AId==4将匹配除5和8之外的所有项目,AId==5将匹配所有8个项目


最好的方法是什么?这个查询在Spark中似乎很昂贵,而且Spark没有内置的。另一种选择似乎是A1-A4设置一个标志,然后返回并加入。另一个棘手的问题是,通配符可能会在第一个表的任何列中出现1-4次,尽管它们不会出现在第二个表中。

您可以将连接条件表示为:

(A1 = * | (A1 = B1)) AND (A2 = * | (A2 = B2)) AND ... AND (AN = * | (AN = BN))
例如,使用PySpark可以生成如下等效表达式

从pyspark.sql.functions导入col
从functools导入reduce
从操作员导入和_
expr=减少(
而且,,
((col(“A{}.format(i))==“*”))(col(“A{}.format(i))==col(“B{}.format(i)))
对于(1,5)范围内的i)
并与交叉连接一起使用:

a.交叉连接(b).其中(expr)

spark.conf.set(“spark.sql.crossJoin.enabled”,“true”)
a、 加入(b,expr)
不幸的是,由于笛卡尔积,这相当昂贵。对于少量的列(4可能是一种边界情况),您可以尝试生成一组列并创建优化的计划,但显然它不会扩展到更多的列