Introduction
Spark SQL provides built-in standard map functions defined in the DataFrame API, which come in handy when you need to perform operations on map (MapType) columns. All these functions accept input as a map column and several other arguments based on the functions.
Spark SQL map functions are grouped as “collection_funcs” in Spark SQL along with several array functions. These map functions are useful when you want to concatenate two or more map columns, convert arrays of StructType entries to a map column, etc.
| Function | Description | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | map_keys | Returns an array containing the keys of the map. | | map_values | Returns an array containing the values of the map. | | map_concat | Merges maps specified in the arguments. | | map_from_entries | Returns a map from the given array of StructType entries. | | map_entries | Returns an array of all StructType in the given map. | | explode() | Creates a new row for every key-value pair in the map by ignoring null & empty values. It creates two new columns, one for key and one for value. | | explode_outer() | Creates a new row for every key-value pair in the map, including null & empty values. It creates two new columns, one for key and one for value. | | posexplode() | Creates a new row for each key-value pair in a map by ignoring null & empty values. It also creates 3 columns: “pos” to hold the position of the map element, and “key” and “value” columns for every row. | | posexplode_outer() | Creates a new row for each key-value pair in a map, including null & empty values. It also creates 3 columns: “pos” to hold the position of the map element, and “key” and “value” columns for every row. | | transform_keys() | Transforms a map by applying functions to every key-value pair and returns a transformed map. | | transform_value() | Transforms a map by applying functions to every key-value pair and returns a transformed map. | | map_zip_with() | Merges two maps into a single map. | | element_at() | Returns a value of a key in a map. | | size() | Returns the length of a map column. |
Example: Using map_keys and map_values
import org.apache.spark.sql.functions._
import spark.implicits._
val data = Seq(
(1, Map("key1" -> "value1", "key2" -> "value2")),
(2, Map("key3" -> "value3", "key4" -> "value4"))
)
val df = data.toDF("id", "map")
df.select($"id", map_keys($"map").as("keys"), map_values($"map").as("values")).show(false)
+---+----------+----------+
|id |keys |values |
+---+----------+----------+
|1 |[key1,key2]|[value1,value2]|
|2 |[key3,key4]|[value3,value4]|
+---+----------+----------+
Example: Using map_concat
import org.apache.spark.sql.functions._
val df1 = Seq(
(1, Map("key1" -> "value1")),
(2, Map("key2" -> "value2"))
).toDF("id", "map1")
val df2 = Seq(
(1, Map("key3" -> "value3")),
(2, Map("key4" -> "value4"))
).toDF("id", "map2")
val df = df1.join(df2, "id")
df.withColumn("map_concat", map_concat($"map1", $"map2")).show(false)
+---+----------+----------+-------------------------+
|id |map1 |map2 |map_concat |
+---+----------+----------+-------------------------+
|1 |[key1 -> value1]|[key3 -> value3]|[key1 -> value1, key3 -> value3]|
|2 |[key2 -> value2]|[key4 -> value4]|[key2 -> value2, key4 -> value4]|
+---+----------+----------+-------------------------+
Example: Using map_from_entries
import org.apache.spark.sql.functions._
import spark.implicits._
val data = Seq(
(1, Array(("key1", "value1"), ("key2", "value2"))),
(2, Array(("key3", "value3"), ("key4", "value4")))
)
val df = data.toDF("id", "entries")
df.withColumn("map", map_from_entries($"entries")).show(false)
+---+------------------------+-------------------------+
|id |entries |map |
+---+------------------------+-------------------------+
|1 |[[key1,value1],[key2,value2]]|[key1 -> value1, key2 -> value2]|
|2 |[[key3,value3],[key4,value4]]|[key3 -> value3, key4 -> value4]|
+---+------------------------+-------------------------+
Example: Using posexplode
import org.apache.spark.sql.functions._
import spark.implicits._
val data = Seq(
(1, Map("key1" -> "value1", "key2" -> "value2")),
(2, Map("key3" -> "value3", "key4" -> "value4"))
).toDF("id", "map")
df.select($"id", posexplode($"map")).show(false)
+---+---+----+------+
|id |pos|key |value |
+---+---+----+------+
|1 |0 |key1|value1|
|1 |1 |key2|value2|
|2 |0 |key3|value3|
|2 |1 |key4|value4|
+---+---+----+------+
