MAP

MAP
MAP
是键值对数据类型,用于存储动态属性、名称到值的映射。与
STRUCT
STRUCT
(固定字段名)不同,MAP 的键在运行时确定,适合字段数量不固定的场景。

与复杂类型的选型参考:

类型结构适合场景
MAP<K,V>
MAP<K,V>
键值对,键类型统一动态属性、配置项、名称到值的映射
STRUCT<f:T,...>
STRUCT<f:T,...>
命名字段,类型各异固定结构的对象,字段名在建表时确定
ARRAY<T>
ARRAY<T>
有序列表,元素类型统一标签、评分、ID 列表

语法与定义

类型声明

MAP<keyType, valueType>

  • keyType
    keyType
    :键类型,支持基本类型(
    STRING
    STRING
    INT
    INT
    BIGINT
    BIGINT
    DOUBLE
    DOUBLE
    等),不支持
    ARRAY
    ARRAY
    MAP
    MAP
    STRUCT
    STRUCT
  • valueType
    valueType
    :值类型,支持基本类型和复杂类型

构造方式

-- MAP() 构造函数:键值交替排列,参数数量必须为偶数 MAP(key1, value1, key2, value2, ...) -- map_from_arrays():从两个数组分别提供键和值 map_from_arrays(keys_array, values_array)

元素访问:键不存在时返回

NULL
NULL
,不报错:

MAP('a', 1, 'b', 2)['a'] -- 1 MAP('a', 1, 'b', 2)['z'] -- NULL

建表与写入

CREATE TABLE doc_map_demo ( id INT, attrs MAP<STRING, INT>, meta MAP<STRING, STRING> ); INSERT INTO doc_map_demo VALUES (1, MAP('age', 25, 'score', 90), MAP('dept', 'Eng', 'level', 'senior')), (2, MAP('age', 30, 'score', 85), MAP('dept', 'HR', 'level', 'junior')), (3, MAP('age', 28), MAP('dept', 'Eng'));

查询基本信息:

SELECT id, attrs['age'] AS age, attrs['score'] AS score, size(attrs) AS attr_count FROM doc_map_demo ORDER BY id;

idagescoreattr_count
125902
230852
328NULL1

常用函数

函数说明
size(m)
size(m)
/
cardinality(m)
cardinality(m)
键值对数量
map_keys(m)
map_keys(m)
返回所有键组成的 ARRAY
map_values(m)
map_values(m)
返回所有值组成的 ARRAY
element_at(m, key)
element_at(m, key)
按键取值,等价于
m[key]
m[key]
map_from_arrays(keys, values)
map_from_arrays(keys, values)
从两个数组构造 MAP
map_concat(m1, m2, ...)
map_concat(m1, m2, ...)
合并多个 MAP,重复键取后者的值
map_filter(m, (k,v) -> cond)
map_filter(m, (k,v) -> cond)
保留满足条件的键值对
transform_values(m, (k,v) -> expr)
transform_values(m, (k,v) -> expr)
对每个值应用函数,键不变
transform_keys(m, (k,v) -> expr)
transform_keys(m, (k,v) -> expr)
对每个键应用函数,值不变

map_from_arrays 示例

SELECT map_from_arrays(['a', 'b', 'c'], [1, 2, 3]) AS m; -- 返回:{"a":1,"b":2,"c":3}

map_concat 示例

重复键取后者的值:

SELECT map_concat(MAP('a', 1, 'b', 2), MAP('b', 99, 'c', 3)) AS merged; -- 返回:{"a":1,"b":99,"c":3}

高阶函数示例

-- 保留值大于 1 的键值对 SELECT map_filter(MAP('a', 1, 'b', 2, 'c', 3), (k, v) -> v > 1) AS filtered; -- 返回:{"b":2,"c":3} -- 所有值乘以 10 SELECT transform_values(MAP('a', 1, 'b', 2), (k, v) -> v * 10) AS scaled; -- 返回:{"a":10,"b":20} -- 键转大写 SELECT transform_keys(MAP('a', 1, 'b', 2), (k, v) -> UPPER(k)) AS upper_keys; -- 返回:{"A":1,"B":2}

聚合与展开

MAP_AGG — 行转 MAP

将多行的键值聚合为一个 MAP:

SELECT MAP_AGG(name, score) AS score_map FROM ( SELECT 'Alice' AS name, 95 AS score UNION ALL SELECT 'Bob', 87 UNION ALL SELECT 'Carol', 92 ) t; -- 返回:{"Alice":95,"Bob":87,"Carol":92}

配合

GROUP BY
GROUP BY
按分组聚合:

SELECT dept, MAP_AGG(name, score) AS scores FROM ( SELECT 'Alice' AS name, 95 AS score, 'Eng' AS dept UNION ALL SELECT 'Bob', 87, 'Eng' UNION ALL SELECT 'Carol', 92, 'HR' ) t GROUP BY dept ORDER BY dept;

deptscores
Eng{"Alice":95,"Bob":87}
HR{"Carol":92}

EXPLODE — MAP 展开为行

EXPLODE
EXPLODE
将 MAP 展开为多行,每行一个键值对:

SELECT id, k, v FROM doc_map_demo LATERAL VIEW EXPLODE(attrs) tmp AS k, v ORDER BY id, k;

idkv
1age25
1score90
2age30
2score85
3age28

类型转换

-- 转换值类型 SELECT CAST(MAP('a', 1, 'b', 2) AS MAP<STRING, BIGINT>) AS cast_map; -- 返回:{"a":1,"b":2}(值类型变为 bigint)

CAST to STRING 与 TO_JSON 的格式区别

SELECT CAST(MAP('a', 1, 'b', 2) AS STRING); -- {a -> 1, b -> 2}(非 JSON 格式) SELECT TO_JSON(MAP('a', 1, 'b', 2)); -- {"a":1,"b":2}(标准 JSON)

NULL 处理

-- NULL 值合法 SELECT MAP('a', NULL, 'b', 2) AS null_val; -- 返回:{"a":null,"b":2} -- 访问值为 NULL 的键,返回 NULL(与键不存在无法区分) SELECT MAP('a', NULL, 'b', 2)['a']; -- NULL SELECT MAP('a', NULL, 'b', 2)['z']; -- NULL

注意事项

  • MAP 不支持
    =
    =
    比较运算符,不能用作
    ORDER BY
    ORDER BY
    GROUP BY
    GROUP BY
    或 JOIN 键。
  • 同一 MAP 中所有键类型必须一致,所有值类型也必须一致。
  • MAP()
    MAP()
    map_from_arrays()
    map_from_arrays()
    均不会自动去重重复键。重复键的行为:
    map_keys
    map_keys
    保留所有重复键,
    m[key]
    m[key]
    返回第一个匹配值,
    TO_JSON
    TO_JSON
    保留所有重复键(如
    {"k":1,"k":2}
    {"k":1,"k":2}
    )。构建 MAP 前应确保键唯一。
  • map_keys
    map_keys
    map_values
    map_values
    返回的数组顺序与插入顺序一致,但不保证跨版本稳定。

相关文档

联系我们
预约咨询
微信咨询
电话咨询