【问题标题】:Array Intersection in Spark SQLSpark SQL 中的数组交集
【发布时间】:2017-07-31 04:27:59
【问题描述】:

我有一个表,其中包含一个名为 writer 的数组类型列,其中包含 array[value1, value2]array[value2, value3].... 等值。

我正在做self join 以获得在数组之间具有共同值的结果。我试过了:

sqlContext.sql("SELECT R2.writer FROM table R1 JOIN table R2 ON R1.id != R2.id WHERE ARRAY_INTERSECTION(R1.writer, R2.writer)[0] is not null ")

sqlContext.sql("SELECT R2.writer FROM table R1 JOIN table R2 ON R1.id != R2.id WHERE ARRAY_INTERSECT(R1.writer, R2.writer)[0] is not null ")

但是遇到了同样的异常:

线程“主”org.apache.spark.sql.AnalysisException 中的异常: 未定义的函数:'ARRAY_INTERSECT'。该功能既不是 注册的临时函数或注册的永久函数 数据库'默认'。;第 1 行 pos 80

可能 Spark SQL 不支持ARRAY_INTERSECTIONARRAY_INTERSECT。如何在Spark SQL 中实现我的目标?

【问题讨论】:

    标签: apache-spark apache-spark-sql spark-dataframe hiveql apache-spark-dataset


    【解决方案1】:

    由于 Spark 2.4 array_intersect 函数可以直接在 SQL 中使用

    spark.sql(
      "SELECT array_intersect(array(1, 42), array(42, 3)) AS intersection"
    ).show
    
    +------------+
    |intersection|
    +------------+
    |        [42]|
    +------------+
    

    Dataset API:

    import org.apache.spark.sql.functions.array_intersect
    
    Seq((Seq(1, 42), Seq(42, 3)))
      .toDF("a", "b")
      .select(array_intersect($"a", $"b") as "intersection")
      .show
    
    +------------+
    |intersection|
    +------------+
    |        [42]|
    +------------+
    

    来宾语言中也存在等效函数:

    【讨论】:

      【解决方案2】:

      你需要一个 udf:

      import org.apache.spark.sql.functions.udf
      
      spark.udf.register("array_intersect", 
        (xs: Seq[String], ys: Seq[String]) => xs.intersect(ys))
      

      然后检查交点是否为空:

      scala> spark.sql("SELECT size(array_intersect(array('1', '2'), array('3', '4'))) = 0").show
      +-----------------------------------------+
      |(size(UDF(array(1, 2), array(3, 4))) = 0)|
      +-----------------------------------------+
      |                                     true|
      +-----------------------------------------+
      
      
      scala> spark.sql("SELECT size(array_intersect(array('1', '2'), array('1', '4'))) = 0").show
      +-----------------------------------------+
      |(size(UDF(array(1, 2), array(1, 4))) = 0)|
      +-----------------------------------------+
      |                                    false|
      +-----------------------------------------+
      

      【讨论】:

        猜你喜欢
        • 2021-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-04
        • 1970-01-01
        • 2015-09-17
        • 2023-03-22
        • 2022-11-22
        相关资源
        最近更新 更多