MAP | Complex Types
MAP<K, V> 表示由 K, V 类型元素组成的 MAP,常用于存储半结构化的键值对数据。点击 MAP 数据类型 了解具体信息。
本文聚焦于 如何把数据写入 MAP 类型字段,提供两类常见数据源的端到端示例:
两类导入均使用 Stream Load 接口,通用步骤为:
- 准备数据文件
- 在数据库中建表
- 通过
curl调用 Stream Load 导入 - 查询结果以校验
CSV 格式导入
第 1 步:准备数据
创建如下的 CSV 文件 test_map.csv。其中字段分隔符使用 | 而不是逗号,以便和 MAP 内部的逗号区分。
1|{"Emily":101,"age":25}
2|{"Benjamin":102}
3|{}
4|null
文件中各行的语义如下:
| 行 | 含义 |
|---|---|
1|{"Emily":101,"age":25} | 包含两个键值对的 MAP |
2|{"Benjamin":102} | 包含一个键值对的 MAP |
3|{} | 空 MAP |
4|null | NULL 值 |
第 2 步:在数据库中建表
CREATE TABLE map_test (
id INT NOT NULL,
c_map MAP<STRING, INT> NULL
)
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
第 3 步:导入数据
通过 Stream Load 将 CSV 文件导入,关键 Header 含义见下表。
curl --location-trusted \
-u "root":"" \
-H "column_separator:|" \
-H "columns: id, c_map" \
-T "test_map.csv" \
http://localhost:8040/api/testdb/map_test/_stream_load
| Header | 作用 |
|---|---|
| `column_separator: | ` |
columns: id, c_map | 声明文件列与表列的映射关系 |
第 4 步:检查导入数据
mysql> SELECT * FROM map_test;
+------+-------------------------+
| id | c_map |
+------+-------------------------+
| 1 | {"Emily":101, "age":25} |
| 2 | {"Benjamin":102} |
| 3 | {} |
| 4 | NULL |
+------+-------------------------+
4 rows in set (0.01 sec)
JSON 格式导入
第 1 步:准备数据
创建如下的 JSON 文件 test_map.json,整体为 JSON 数组,每个元素对应一行数据。
[
{"id":1, "c_map":{"Emily":101, "age":25}},
{"id":2, "c_map":{"Benjamin":102}},
{"id":3, "c_map":{}},
{"id":4, "c_map":null}
]
第 2 步:在数据库中建表
CREATE TABLE map_test (
id INT NOT NULL,
c_map MAP<STRING, INT> NULL
)
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
第 3 步:导入数据
通过 Stream Load 将 JSON 文件导入,关键 Header 含义见下表。
curl --location-trusted \
-u "root":"" \
-H "format:json" \
-H "columns: id, c_map" \
-H "strip_outer_array:true" \
-T "test_map.json" \
http://localhost:8040/api/testdb/map_test/_stream_load
| Header | 作用 |
|---|---|
format:json | 声明数据格式为 JSON |
strip_outer_array:true | 当输入为 JSON 数组时,按数组元素逐行解析 |
columns: id, c_map | 声明 JSON 字段与表列的映射关系 |
第 4 步:检查导入数据
mysql> SELECT * FROM map_test;
+------+-------------------------+
| id | c_map |
+------+-------------------------+
| 1 | {"Emily":101, "age":25} |
| 2 | {"Benjamin":102} |
| 3 | {} |
| 4 | NULL |
+------+-------------------------+
4 rows in set (0.01 sec)
常见问题
Q1:CSV 中为什么不使用逗号作为列分隔符?
MAP 字面量内部本身就使用逗号分隔多个键值对(例如 {"Emily":101,"age":25})。如果列分隔符也使用逗号,会导致解析歧义。建议使用 |、\t 等不会出现在 MAP 内容中的字符。
Q2:导入 JSON 数组时为什么要加 strip_outer_array:true?
当 JSON 文件最外层是一个数组(如本文示例)时,需要设置 strip_outer_array:true,Doris 才会把数组中的每个元素当作一行数据处理。如果文件本身已是 JSON Lines(每行一个对象),则无需该参数。
Q3:如何表示空 MAP 与 NULL?
- 空 MAP:CSV 中写为
{},JSON 中写为{}。 - NULL 值:CSV 中写为
null,JSON 中写为null,要求目标列允许NULL。