跳到主要内容

BITMAP

BITMAP 类型常用于精确去重、用户画像标签等场景。本文介绍 BITMAP 列在 Apache Doris 中的建表规范,并通过 Stream Load 演示单值与多元素两种导入方式。

BITMAP 类型使用约束

在导入 BITMAP 数据前,请先了解以下约束:

约束项说明
适用表模型Duplicate 表、Unique 表、Aggregate 表
列位置仅可作为 Value 列,不能作为 Key 列
聚合表要求在 Aggregate 表中必须使用聚合类型 BITMAP_UNION
长度与默认值无需指定长度和默认值,长度由系统根据聚合程度自动控制

更多类型说明请参考 BITMAP 数据类型

场景一:导入单值 BITMAP 数据

适用于源数据中每行只包含一个整数值的场景,使用 to_bitmap 函数将单个整数转换为 BITMAP。

第 1 步:准备数据

创建 CSV 文件 test_bitmap.csv,每行包含一个整数值:

1|koga|17723
2|nijg|146285
3|lojn|347890
4|lofn|489871
5|jfin|545679
6|kon|676724
7|nhga|767689
8|nfubg|879878
9|huang|969798
10|buag|97997

第 2 步:创建目标表

testdb 库中创建包含 BITMAP 列的聚合表:

CREATE TABLE testdb.test_bitmap(
typ_id BIGINT NULL COMMENT "ID",
hou VARCHAR(10) NULL COMMENT "one",
arr BITMAP BITMAP_UNION NOT NULL COMMENT "two"
)
AGGREGATE KEY(typ_id,hou)
DISTRIBUTED BY HASH(typ_id,hou) BUCKETS 10;

第 3 步:执行 Stream Load 导入

通过 to_bitmap 函数将整数列转换为 BITMAP:

curl --location-trusted -u <doris_user>:<doris_password> \
-H "column_separator:|" \
-H "columns:typ_id,hou,arr,arr=to_bitmap(arr)" \
-T test_bitmap.csv \
-XPUT http://<fe_ip>:<fe_http_port>/api/testdb/test_bitmap/_stream_load

第 4 步:验证导入结果

使用 bitmap_to_string 将 BITMAP 转回字符串以查看导入数据:

mysql> select typ_id,hou,bitmap_to_string(arr) from testdb.test_bitmap;
+--------+-------+-----------------------+
| typ_id | hou | bitmap_to_string(arr) |
+--------+-------+-----------------------+
| 4 | lofn | 489871 |
| 6 | kon | 676724 |
| 9 | huang | 969798 |
| 3 | lojn | 347890 |
| 8 | nfubg | 879878 |
| 7 | nhga | 767689 |
| 1 | koga | 17723 |
| 2 | nijg | 146285 |
| 5 | jfin | 545679 |
| 10 | buag | 97997 |
+--------+-------+-----------------------+
10 rows in set (0.07 sec)

场景二:导入多元素 BITMAP 数据

当源数据中每行包含多个整数(例如多个用户 ID)时,可根据源文件格式选择以下两种方法之一。两种方法的差异如下:

方法源文件格式是否需要 cast 转换备注
bitmap_from_string逗号分隔,不允许方括号出现方括号会被判定为数据质量错误
bitmap_from_array逗号分隔,允许方括号必须 castarray<int>不做 cast 会因函数签名匹配失败而报错

方式 A:使用 bitmap_from_string

数据格式要求

源文件 arr 列使用逗号分隔,不能包含方括号:

1|koga|17,723
2|nijg|146,285
3|lojn|347,890
4|lofn|489,871
5|jfin|545,679
6|kon|676,724
7|nhga|767,689
8|nfubg|879,878
9|huang|969,798
10|buag|97,997

Stream Load 命令

curl --location-trusted -u <doris_user>:<doris_password> \
-H "column_separator:|" \
-H "columns:typ_id,hou,arr,arr=bitmap_from_string(arr)" \
-T test_bitmap.csv \
-XPUT http://<fe_ip>:<fe_http_port>/api/testdb/test_bitmap/_stream_load

方式 B:使用 bitmap_from_array

数据格式要求

源文件 arr 列允许包含方括号:

1|koga|[17,723]
2|nijg|[146,285]
3|lojn|[347,890]
4|lofn|[489,871]
5|jfin|[545,679]
6|kon|[676,724]
7|nhga|[767,689]
8|nfubg|[879,878]
9|huang|[969,798]
10|buag|[97,997]

Stream Load 命令

在 Stream Load 中必须先将字符串 castarray<int>,再通过 bitmap_from_array 转换:

curl --location-trusted -u <doris_user>:<doris_password> \
-H "column_separator:|" \
-H "columns:typ_id,hou,arr_str,arr=bitmap_from_array(cast(arr_str as array<int>))" \
-T test_bitmap.csv \
-XPUT http://<fe_ip>:<fe_http_port>/api/testdb/test_bitmap/_stream_load

常见问题(Troubleshooting)

使用 bitmap_from_array 时报函数不存在错误

报错示例:

[ANALYSIS_ERROR]TStatus: errCode = 2, detailMessage = Does not support non-builtin functions, or function does not exist: bitmap_from_array(<slot 8>)
  • 原因:未将 string 类型显式转换为 array<int>,导致无法匹配 bitmap_from_array 的函数签名。
  • 解决方法:在 Stream Load 的 columns 参数中使用 cast(arr_str as array<int>) 显式转换。

如何在查询时查看 BITMAP 列内容

BITMAP 是二进制聚合类型,无法直接 SELECT 查看,需要通过函数转换:

  • bitmap_to_string(col):将 BITMAP 转换为逗号分隔的字符串。
  • bitmap_count(col):返回 BITMAP 中元素的去重数量。

为什么 BITMAP 不能作为 Key 列

BITMAP 是聚合二进制类型,不支持作为 Key 列参与排序与去重,仅能作为 Value 列存储聚合结果。