Apache spark 根据spark Scala中的以下逻辑在spark中生成ID

Apache spark 根据spark Scala中的以下逻辑在spark中生成ID,apache-spark,pyspark,apache-spark-sql,pyspark-dataframes,Apache Spark,Pyspark,Apache Spark Sql,Pyspark Dataframes,我有一个数据框,其中包含如下所示的父\u id、服务\u id、产品\u关系\u id、产品\u名称字段,我想分配id字段,如下表所示, 请注意 一个父id有多个服务id 一个服务\u id有多个产品\u名称 ID生成应遵循以下模式 父项--1.n 儿童1--1.n.1 儿童2--1.n.2 儿童3--1.n.3 儿童4--1.n.4 我们如何以同时考虑大数据性能的方式实现这一逻辑 Scala实现 import org.apache.spark.sql.expressions.Window

我有一个数据框,其中包含如下所示的父\u id、服务\u id、产品\u关系\u id、产品\u名称字段,我想分配id字段,如下表所示, 请注意

  • 一个父id有多个服务id

  • 一个服务\u id有多个产品\u名称

  • ID生成应遵循以下模式

  • 父项--1.n 儿童1--1.n.1 儿童2--1.n.2 儿童3--1.n.3 儿童4--1.n.4

    我们如何以同时考虑大数据性能的方式实现这一逻辑

    Scala实现

    import org.apache.spark.sql.expressions.Window
    import org.apache.spark.sql.functions._
    
    val parentWindowSpec = Window.orderBy("parent_id")
    val childWindowSpec = Window.partitionBy(
        "parent_version", "service_id"
        ).orderBy("product_relation_id")
    
    
    val df = spark.read.options(
        Map("inferSchema"->"true","delimiter"->",","header"->"true")
        ).csv("product.csv")
    
    val df2 = df.withColumn(
        "parent_version", dense_rank.over(parentWindowSpec)
        ).withColumn(
        "child_version",row_number.over(childWindowSpec) - 1)
    
    val df3 = df2.withColumn("id", 
        when(col("product_name") === lit("Parent"), 
            concat(lit("1."), col("parent_version")))
        .otherwise(concat(lit("1."), col("parent_version"),lit("."),col("child_version")))
    ).drop("parent_version").drop("child_version")
    
    输出:

    scala> df3.show
    21/03/26 11:55:01 WARN WindowExec: No Partition Defined for Window operation! Moving all data to a single partition, this can cause serious performance degradation.
    +---------+----------+-------------------+------------+-----+
    |parent_id|service_id|product_relation_id|product_name|   id|
    +---------+----------+-------------------+------------+-----+
    |      100|         1|                1-A|      Parent|  1.1|
    |      100|         1|                1-A|      Child1|1.1.1|
    |      100|         1|                1-A|      Child2|1.1.2|
    |      100|         1|                1-A|      Child3|1.1.3|
    |      100|         1|                1-A|      Child4|1.1.4|
    |      100|         2|                1-B|      Parent|  1.1|
    |      100|         2|                1-B|      Child1|1.1.1|
    |      100|         2|                1-B|      Child2|1.1.2|
    |      100|         2|                1-B|      Child3|1.1.3|
    |      100|         2|                1-B|      Child4|1.1.4|
    |      100|         3|                1-C|      Parent|  1.1|
    |      100|         3|                1-C|      Child1|1.1.1|
    |      100|         3|                1-C|      Child2|1.1.2|
    |      100|         3|                1-C|      Child3|1.1.3|
    |      100|         3|                1-C|      Child4|1.1.4|
    |      200|         5|                1-D|      Parent|  1.2|
    |      200|         5|                1-D|      Child1|1.2.1|
    |      200|         5|                1-D|      Child2|1.2.2|
    |      200|         5|                1-D|      Child3|1.2.3|
    |      200|         5|                1-D|      Child4|1.2.4|
    +---------+----------+-------------------+------------+-----+
    only showing top 20 rows
    

    当我试图转换此代码时,spark scala中几乎没有错误:27:错误:类型不匹配;找到:org.apache.spark.sql.Column required:StringConverted pyspark代码到scala,如果这解决了问题,请告诉我。谢谢,它可以工作:-)