简体   繁体   English

如何在 Spark 数据框中使用嵌套列进行连接

[英]How to join using a nested column in Spark dataframe

I have one dataframe with this schema:我有一个具有此架构的数据框:

|-- Activity_A1: string (nullable = true)
|-- Activity_A2: string (nullable = true)
|-- Details: array (nullable = true)
|    |-- element: struct (containsNull = true)
|    |    |-- Agreement_A1: string (nullable = true)
|    |    |-- Agreement_A2: string (nullable = true)

data:数据:

+-----------+-----------+--------------------------------------------------+
|Activity_A1|Activity_A2|Details                                           |
+-----------+-----------+--------------------------------------------------+
|Act1_Attr1 |Act1_Attr2 |[[Agr2_Attr1,Agr2_Attr2], [Agr1_Attr1,Agr1_Attr2]]|
|Act2_Attr1 |Act2_Attr2 |[[Agr4_Attr1,Agr4_Attr2], [Agr3_Attr1,Agr3_Attr2]]|
|Act3_Attr1 |Act3_Attr2 |[[Agr5_Attr1,Agr5_Attr2]]                         |
+-----------+-----------+--------------------------------------------------+

And the second one with this schema:使用此架构的第二个:

|-- Agreement_A1: string (nullable = true)
|    |    |-- Lines: array (nullable = true)
|    |    |    |-- element: struct (containsNull = true)
|    |    |    |    |-- Line_A1: string (nullable = true)
|    |    |    |    |-- Line_A2: string (nullable = true)

How can I join this two dataframes with the Agreement_A1 column, so the schema of this new dataframe would look like this:如何将这两个数据框与 Agreement_A1 列连接起来,因此这个新数据框的架构如下所示:

|-- Activity_A1: string (nullable = true)
|-- Activity_A2: string (nullable = true)
|-- Details: array (nullable = true)
|    |-- element: struct (containsNull = true)
|    |    |-- Agreement_A1: string (nullable = true)
|    |    |-- Agreement_A2: string (nullable = true)
|    |    |-- Lines: array (nullable = true)
|    |    |    |-- element: struct (containsNull = true)
|    |    |    |    |-- Line_A1: string (nullable = true)
|    |    |    |    |-- Line_A2: string (nullable = true)

Hope this helps.希望这可以帮助。 You need to unnest (explode) "Details" and join on "Agreement_A1" with your second dataframe.您需要取消嵌套(分解)“详细信息”并使用您的第二个数据框加入“Agreement_A1”。 Then, structure your columns as desired.然后,根据需要构建您的列。

scala> df1.show(false)
+-----------+-----------+----------------------------------------------------+
|Activity_A1|Activity_A2|Details                                             |
+-----------+-----------+----------------------------------------------------+
|Act1_Attr1 |Act1_Attr2 |[[Agr2_Attr1, Agr2_Attr2], [Agr1_Attr1, Agr1_Attr2]]|
|Act2_Attr1 |Act2_Attr2 |[[Agr4_Attr1, Agr4_Attr2], [Agr3_Attr1, Agr3_Attr2]]|
|Act3_Attr1 |Act3_Attr2 |[[Agr5_Attr1, Agr5_Attr2]]                          |
+-----------+-----------+----------------------------------------------------+


scala> df1.printSchema
root
|-- Activity_A1: string (nullable = true)
|-- Activity_A2: string (nullable = true)
|-- Details: array (nullable = true)
|    |-- element: struct (containsNull = true)
|    |    |-- Agreement_A1: string (nullable = true)
|    |    |-- Agreement_A2: string (nullable = true)


scala> df2.show(false)
+------------+--------------------------+
|Agreement_A1|Lines                     |
+------------+--------------------------+
|Agr1_Attr1  |[[A1At1Line1, A1At1Line2]]|
|Agr3_Attr1  |[[A3At1Line1, A3At1Line2]]|
|Agr4_Attr1  |[[A4At1Line1, A4At1Line2]]|
|Agr5_Attr1  |[[A5At1Line1, A5At1Line2]]|
|Agr6_Attr1  |[[A6At1Line1, A6At1Line2]]|
+------------+--------------------------+


scala> df2.printSchema
root
|-- Agreement_A1: string (nullable = true)
|-- Lines: array (nullable = true)
|    |-- element: struct (containsNull = true)
|    |    |-- Line_A1: string (nullable = true)
|    |    |-- Line_A2: string (nullable = true)


scala> val outputDF = df1.withColumn("DetailsExploded", explode($"Details")).join(
    |   df2, $"DetailsExploded.Agreement_A1" === $"Agreement_A1").withColumn(
    |     "DetailsWithAgreementA1Lines", struct($"DetailsExploded.Agreement_A1" as "Agreement_A1", $"DetailsExploded.Agreement_A2" as "Agreement_A2", $"Lines"))
outputDF: org.apache.spark.sql.DataFrame = [Activity_A1: string, Activity_A2: string ... 5 more fields]

scala> outputDF.show(false)
+-----------+-----------+----------------------------------------------------+------------------------+------------+--------------------------+----------------------------------------------------+
|Activity_A1|Activity_A2|Details                                             |DetailsExploded         |Agreement_A1|Lines                     |DetailsWithAgreementA1Lines                         |
+-----------+-----------+----------------------------------------------------+------------------------+------------+--------------------------+----------------------------------------------------+
|Act1_Attr1 |Act1_Attr2 |[[Agr2_Attr1, Agr2_Attr2], [Agr1_Attr1, Agr1_Attr2]]|[Agr1_Attr1, Agr1_Attr2]|Agr1_Attr1  |[[A1At1Line1, A1At1Line2]]|[Agr1_Attr1, Agr1_Attr2, [[A1At1Line1, A1At1Line2]]]|
|Act2_Attr1 |Act2_Attr2 |[[Agr4_Attr1, Agr4_Attr2], [Agr3_Attr1, Agr3_Attr2]]|[Agr3_Attr1, Agr3_Attr2]|Agr3_Attr1  |[[A3At1Line1, A3At1Line2]]|[Agr3_Attr1, Agr3_Attr2, [[A3At1Line1, A3At1Line2]]]|
|Act2_Attr1 |Act2_Attr2 |[[Agr4_Attr1, Agr4_Attr2], [Agr3_Attr1, Agr3_Attr2]]|[Agr4_Attr1, Agr4_Attr2]|Agr4_Attr1  |[[A4At1Line1, A4At1Line2]]|[Agr4_Attr1, Agr4_Attr2, [[A4At1Line1, A4At1Line2]]]|
|Act3_Attr1 |Act3_Attr2 |[[Agr5_Attr1, Agr5_Attr2]]                          |[Agr5_Attr1, Agr5_Attr2]|Agr5_Attr1  |[[A5At1Line1, A5At1Line2]]|[Agr5_Attr1, Agr5_Attr2, [[A5At1Line1, A5At1Line2]]]|
+-----------+-----------+----------------------------------------------------+------------------------+------------+--------------------------+----------------------------------------------------+


scala> outputDF.printSchema
root
|-- Activity_A1: string (nullable = true)
|-- Activity_A2: string (nullable = true)
|-- Details: array (nullable = true)
|    |-- element: struct (containsNull = true)
|    |    |-- Agreement_A1: string (nullable = true)
|    |    |-- Agreement_A2: string (nullable = true)
|-- DetailsExploded: struct (nullable = true)
|    |-- Agreement_A1: string (nullable = true)
|    |-- Agreement_A2: string (nullable = true)
|-- Agreement_A1: string (nullable = true)
|-- Lines: array (nullable = true)
|    |-- element: struct (containsNull = true)
|    |    |-- Line_A1: string (nullable = true)
|    |    |-- Line_A2: string (nullable = true)
|-- DetailsWithAgreementA1Lines: struct (nullable = false)
|    |-- Agreement_A1: string (nullable = true)
|    |-- Agreement_A2: string (nullable = true)
|    |-- Lines: array (nullable = true)
|    |    |-- element: struct (containsNull = true)
|    |    |    |-- Line_A1: string (nullable = true)
|    |    |    |-- Line_A2: string (nullable = true)



scala> outputDF.groupBy("Activity_A1", "Activity_A2").agg(collect_list($"DetailsWithAgreementA1Lines") as "Details").show(false)
+-----------+-----------+------------------------------------------------------------------------------------------------------------+
|Activity_A1|Activity_A2|Details                                                                                                     |
+-----------+-----------+------------------------------------------------------------------------------------------------------------+
|Act1_Attr1 |Act1_Attr2 |[[Agr1_Attr1, Agr1_Attr2, [[A1At1Line1, A1At1Line2]]]]                                                      |
|Act2_Attr1 |Act2_Attr2 |[[Agr3_Attr1, Agr3_Attr2, [[A3At1Line1, A3At1Line2]]], [Agr4_Attr1, Agr4_Attr2, [[A4At1Line1, A4At1Line2]]]]|
|Act3_Attr1 |Act3_Attr2 |[[Agr5_Attr1, Agr5_Attr2, [[A5At1Line1, A5At1Line2]]]]                                                      |
+-----------+-----------+------------------------------------------------------------------------------------------------------------+


scala> outputDF.groupBy("Activity_A1", "Activity_A2").agg(collect_list($"DetailsWithAgreementA1Lines") as "Details").printSchema
root
|-- Activity_A1: string (nullable = true)
|-- Activity_A2: string (nullable = true)
|-- Details: array (nullable = true)
|    |-- element: struct (containsNull = true)
|    |    |-- Agreement_A1: string (nullable = true)
|    |    |-- Agreement_A2: string (nullable = true)
|    |    |-- Lines: array (nullable = true)
|    |    |    |-- element: struct (containsNull = true)
|    |    |    |    |-- Line_A1: string (nullable = true)
|    |    |    |    |-- Line_A2: string (nullable = true)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM