Entonces tengo una tabla con una columna de tipo de mapa (la clave y el valor son ambas cadenas).

Me gustaría escribir spark sql como este para verificar si la clave dada existe en el mapa.

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

No pude encontrar ninguna función existente de spark sql que pueda hacer esto.

¿Alguna idea?

Gracias

3
seiya 7 sep. 2018 a las 20:51

3 respuestas

La mejor respuesta

Lo averigué. La siguiente consulta SQL funciona

select count(*) from my_table where map_column["testKey"] is not null
2
seiya 7 sep. 2018 a las 19:37

La solución no funcionará si testKey no está en el esquema de DataFrame, esto producirá un error No such struct field.

Debe escribir un pequeño UDF para verificar, como este:

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
0
Thomas Decaux 28 jun. 2019 a las 10:06

Tal construcción se puede utilizar:

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

Para sql puro:

spark.sql("select * from my_table where mapColumn[\"testKey\"] is not null")
6
pasha701 7 sep. 2018 a las 20:23