【问题标题】:How to check if key exists in spark sql map type如何检查火花 sql 映射类型中是否存在密钥
【发布时间】:2018-09-07 17:51:43
【问题描述】:

所以我有一张表,其中有一列是地图类型(键和值都是字符串)。

我想像这样编写 spark sql 来检查地图中是否存在给定的键。

select count(*) from my_table where map_contains_key(map_column, "testKey")

我找不到任何可以执行此操作的现有 spark sql 函数。

有什么想法吗?

谢谢

【问题讨论】:

  • 你可以先炸开你的地图,然后过滤出想要的键,然后计数
  • 想通了,"select count(*) from my_table where map_column["testKey"] is not null" 可以解决问题

标签: apache-spark apache-spark-sql


【解决方案1】:

可以使用这样的构造:

df.where($"map_column"("testKey").isNotNull)

对于纯sql:

spark.sql("select * from my_table where mapColumn[\"testKey\"] is not null")

【讨论】:

  • 嗨,我知道这行得通,只是想知道如何用纯 spark sql 来做。
【解决方案2】:

想通了。以下sql查询有效

select count(*) from my_table where map_column["testKey"] is not null

【讨论】:

    【解决方案3】:

    如果testKey 不在DataFrame 架构中,该解决方案将不起作用,这将产生No such struct field 错误。

    你必须写一个小的UDF来检查,像这样:

    import org.apache.spark.sql.functions.udf
    import org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema
    import org.apache.spark.sql.Row
    
    spark.udf.register("struct_get", (root:GenericRowWithSchema, path: String, defaultValue: String) => {
    
        var fields = path.split("\\.")
        var buffer:Row = root
        val lastItem = fields.last
    
        fields = fields.dropRight(1)
    
        fields.foreach( (field:String) => {
            if (buffer != null) {
                if (buffer.schema.fieldNames.contains(field)) {
                    buffer = buffer.getStruct(buffer.fieldIndex(field))
                } else {
                    buffer = null
                }
            }
        })
    
        if (buffer == null) {
            defaultValue
        } else {
            buffer.getString(buffer.fieldIndex(lastItem))
        }
    })
    
    SELECT struct_get(mapColumn, "testKey", "") FROM my_table
    

    【讨论】:

      【解决方案4】:

      自 Spark 3.0 起

      select * FROM table WHERE EXISTS (map_keys(field), x -> x == 'value')
      

      【讨论】:

        猜你喜欢
        • 2020-08-28
        • 2020-08-27
        • 1970-01-01
        • 2013-07-03
        • 1970-01-01
        • 2015-07-29
        • 2020-08-19
        • 1970-01-01
        相关资源
        最近更新 更多