如何检查Spark SQL Map类型中是否存在密钥

时间:2018-09-07 17:51:44

标签: apache-spark apache-spark-sql

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

我想像这样编写spark sql,以检查给定密钥是否存在于地图中。

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

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

有什么想法吗?

谢谢

3 个答案:

答案 0 :(得分:3)

可以使用这种构造:

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

对于纯SQL:

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

答案 1 :(得分:0)

弄清楚了。以下sql查询有效

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

答案 2 :(得分:0)

如果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