You need to enable JavaScript to run this app.
文档中心
ByteHouse云数仓版

ByteHouse云数仓版

复制全文
下载 pdf
函数参考
BitMap函数
复制全文
下载 pdf
BitMap函数

背景信息

ClickHouse社区提供了 bitmap 数据处理能力,详见Bitmap Functions | ClickHouse Docs ,在差不多同期,ByteHouse 也自研了一套处理 bitmap 数据的类型和相关函数,两者在数据存储和使用方法上存在一定异同,更多关于BitMap类型数据的对比介绍请参见BitMap64类型文档。
ByteHouse为您提供了丰富的函数接口便于您查询BitMap64类型的数据,可大致分为普通函数、聚合函数、高阶聚合函数等类型,以下为您介绍ByteHouse的BitMap函数的接口list和使用说明。

普通函数

ByteHouse的BitMap普通函数接收一行记录或者一个BitMap64对象,返回一行结果。
这部分的函数接口,除第一个函数arrayToBitmap外,其它的均和社区函数接口保持一致。

序号

函数接口

参数说明

返回值

功能释义

1

arrayToBitmap([x1, …])
-> bitmap

UIntN类型的数组
N={8, 16, 32, 64}

BitMap64对象

通过一个数组构造一个bitmap对象

2

bitmapToArray(bitmap)
-> [x1,...]

一个BitMap64对象

UInt64数组

将一个bimap对象转换为数组格式

3

bitmapAnd(bitmap1, bitmap2)
-> bitmap

两个BitMap64对象

BitMap64对象

bitmap的运算

4

bitmapOr(bitmap1, bitmap2)
-> bitmap

两个BitMap64对象

BitMap64对象

bitmap的运算

5

bitmapXor(bitmap1, bitmap2)
-> bitmap

两个BitMap64对象

BitMap64对象

bitmap的异或运算

6

bitmapAndnot(bitmap1, bitmap2)
-> bitmap

两个BitMap64对象

BitMap64对象

bitmap的运算

7

bitmapCardinality(bitmap)
-> integer

一个BitMap64对象

UInt64数值

bitmap中元素的个数

8

bitmapMin(bitmap)
-> integer

一个BitMap64对象

UInt64数值

bitmap中最小的元素

9

bitmapMax(bitmap)
-> integer

一个BitMap64对象

UInt64数值

bitmap中最大的元素

10

bitmapAndCardinality
(bitmap1, bitmap2)
-> integer

两个BitMap64对象

UInt64数值

bitmap的运算之后的元素个数

11

bitmapOrCardinality
(bitmap1, bitmap2)
-> integer

两个BitMap64对象

UInt64数值

bitmap的运算之后的元素个数

12

bitmapXorCardinality
(bitmap1, bitmap2)
-> integer

两个BitMap64对象

UInt64数值

bitmap的异或运算之后的元素个数

13

bitmapAndnotCardinality
(bitmap1, bitmap2)
-> integer

两个BitMap64对象

UInt64数值

bitmap的运算之后的元素个数

14

bitmapContains(bitmap, integer)
-> bool

一个BitMap64对象
UIntN类型的数字,
N={8, 16, 32, 64}

UInt8枚举
1->true
0->false

检查bitmap中是否包含指定元素

15

bitmapHasAll
(bitmap, sub_bitmap)
-> bool

两个BitMap64对象

UInt8枚举
1->true
0->false

检查sub_bitmap是否是bitmap的子集
(相等也返回1)

16

bitmapHasAny
(bitmap1, bitmap2)
-> bool

两个BitMap64对象

UInt8枚举
1->true
0->false

检查两个bitmap是否存在交集

17

bitmapSubsetInRange
(bitmap, range_start, range_end)
-> bitmap

一个BitMap64对象,两个UIntN数字,标识取值范围
N={8, 16, 32, 64}

BitMap64对象

检查并返回bitmap中符合给定元素大小范围的值组成的bitmap。
函数过滤的是数据,返回的 bitmap中元素均大于等于 range_start,且小于 range_end。

18

bitmapSubsetLimit
(bitmap, range_start, cardinality_limit)
-> bitmap

一个BitMap64对象,两个UIntN数字,标识下标启示范围,和子集大小

BitMap64对象

检查并返回由bitmap中指定元素开始的,不超过指定数量的元素组成的bitmap。
函数过滤的是数据,返回的 bitmap 中元素聚大于等于 range_start,且总共的元素个数不超过 cardinality_limit。

19

subBitmap(bitmap, start_offset, length)

一个BitMap64对象,
两个UIntN类型的数字,
N={8, 16, 32, 64}

BitMap64对象

提取bitmap中指定下标范围的数据,类比subString。
需要注意,start_offset从0开始,代表实际存储的第一个有效值,类似于数组下标。start_offset和 length 超过 bitmap 元素个数均无意义。

bitmapAnd

将两个位图进行相加计算,结果是一个新的位图。
语法

bitmapAnd(bitmap,bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 位图对象

示例

SELECT bitmapToArray(bitmapAnd(bitmapBuild([1,2,3]),bitmapBuild([3,4,5]))) AS res;

结果:

┌─res─┐
│ [3] │
└─────┘

bitmapAndCardinality

两个位图的和计算,返回 UInt64 类型的基数。
语法

bitmapAndCardinality(bitmap,bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 类型中的基数UInt64

类型:Uint64
示例

SELECT bitmapAndCardinality(bitmapBuild([1,2,3]),bitmapBuild([3,4,5])) AS res;

结果:

┌─res─┐
│ 1   │
└─────┘

bitmapAndnot

两个位图的和不进行计算,结果是一个新的位图。
语法

bitmapAndnot(bitmap,bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 位图对象

类型:Bitmap object
示例

SELECT bitmapToArray(bitmapAndnot(bitmapBuild([1,2,3]),bitmapBuild([3,4,5]))) AS res;

结果:

┌─res────┐
│ [1, 2] │
└────────┘
纯文本

bitmapAndnotCardinality

两个位图的与不计算,返回 UInt64 类型的基数。
语法

bitmapAndnotCardinality(bitmap,bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 中的基数UInt64

类型:UInt64
示例

SELECT bitmapAndnotCardinality(bitmapBuild([1,2,3]),bitmapBuild([3,4,5])) AS res;

结果:

┌─res─┐
│ 2   │
└─────┘

bitmapBuild

从无符号整数数组构建位图。
语法

bitmapBuild(array)

参数

  • array– 无符号整数数组。

返回值

  • 位图对象

类型:Bitmap object
示例

SELECT toTypeName(bitmapBuild([1, 2, 3, 4, 5]));

结果:

┌─toTypeName(bitmapBuild([1, 2, 3, 4, 5]))─┐
│ AggregateFunction(groupBitmap, UInt8)    │
└──────────────────────────────────────────┘

bitmapCardinality

返回 UInt64 类型的位图基数。
语法

bitmapCardinality(bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 类型中的位图基数UInt64

类型:UInt64
示例

SELECT bitmapCardinality(bitmapBuild([1, 2, 3, 4, 5])) AS res;

结果:

┌─res─┐
│ 5   │
└─────┘

bitmapContains

检查位图是否包含元素。
语法

bitmapContains(haystack, needle)

参数

  • haystack– [位图对象],函数在其中搜索。
  • needle– 函数搜索的值。类型:[UInt32]。

返回值

  • 0 — 如果haystack不包含needle
  • 1 — 如果haystack包含needle

类型:UInt8
示例

SELECT bitmapContains(bitmapBuild([1,5,7,9]), toUInt32(9)) AS res;

结果:

┌─res─┐
│ 1   │
└─────┘

bitmapHasAll

hasAll(array, array)如果第一个位图包含第二个位图的所有元素,则类似于返回 1,否则返回 0。
如果第二个参数是空位图,则返回 1。
语法

bitmapHasAll(bitmap,bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 1,如果第一个位图包含第二个位图的所有元素或第二个参数为空位图,则返回 1。
  • 0, 否则。

类型:UInt8
示例

SELECT bitmapHasAll(bitmapBuild([1,2,3]),bitmapBuild([3,4,5])) AS res;

结果:

┌─res─┐
│ 0   │
└─────┘

bitmapHasAny

检查两个位图是否有某些元素的交集。
语法

bitmapHasAny(bitmap1, bitmap2)

如果您确定bitmap2只包含一个元素,请考虑使用 [bitmapContains] 函数。它工作得更有效率。
参数

  • bitmap*– 位图对象。

返回值

  • 1,若bitmap1bitmap2至少有一个相似元素。
  • 0, 否则。

示例

SELECT bitmapHasAny(bitmapBuild([1,2,3]),bitmapBuild([3,4,5])) AS res;

结果:

┌─res─┐
│ 1   │
└─────┘

bitmapMax

返回集合中 UInt64 类型的最大值,如果集合为空则返回 0。
语法

bitmapMax(bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 返回集合中 UInt64 类型的最大值。

类型:UInt64
示例

SELECT bitmapMax(bitmapBuild([1, 2, 3, 4, 5])) AS res;

结果:

┌─res─┐
│ 5   │
└─────┘

bitmapMin

返回集合中 UInt64 类型的最小值,如果集合为空,则返回 UINT32_MAX。
语法

bitmapMin(bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 返回集合中 UInt64 类型的最小值。

类型:UInt64
示例

SELECT bitmapMin(bitmapBuild([1, 2, 3, 4, 5])) AS res;

结果:

┌─res─┐
│ 1   │
└─────┘

bitmapOr

两个位图进行或计算,结果是一个新的位图。

bitmapOr(bitmap,bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 位图对象

类型:Bitmap object
示例

SELECT bitmapToArray(bitmapOr(bitmapBuild([1,2,3]),bitmapBuild([3,4,5]))) AS res;

结果:

┌─res─────────────┐
│ [1, 2, 3, 4, 5] │
└─────────────────┘

bitmapOrCardinality

两个位图或计算,返回 UInt64 类型的基数。
语法

bitmapOrCardinality(bitmap,bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 以基数形式返回或计算结果。

类型:UInt64
示例

SELECT bitmapOrCardinality(bitmapBuild([1,2,3]),bitmapBuild([3,4,5])) AS res;

结果:

┌─res─┐
│ 5   │
└─────┘

bitmapSubsetInRange

返回指定范围内的子集(不包括range_end)。
语法

bitmapSubsetInRange(bitmap, range_start, range_end)

参数

  • bitmap– [位图对象]。
  • range_start– 范围起点。类型:[UInt32]。
  • range_end– 范围终点(排除)。类型:[UInt32]。

返回值

  • 返回或计算结果。

类型:array
示例

SELECT bitmapToArray(bitmapSubsetInRange(bitmapBuild([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,100,200,500]), toUInt32(30), toUInt32(200))) AS res;

结果:

┌─res───────────────────┐
│ [30, 31, 32, 33, 100] │
└───────────────────────┘

bitmapSubsetLimit

创建位图的子集,其中包含range_start和之间的 n 个元素cardinality_limit
语法

bitmapSubsetLimit(bitmap, range_start, cardinality_limit)

参数

  • bitmap– [位图对象]。
  • range_start– 子集的起点。类型:[UInt32]。
  • cardinality_limit– 子集基数上限。类型:[UInt32]。

返回值

  • 子集。

类型:Bitmap object
示例

SELECT bitmapToArray(bitmapSubsetLimit(bitmapBuild([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,100,200,500]), toUInt32(30), toUInt32(200))) AS res;

结果:

┌─res─────────────────────────────┐
│ [30, 31, 32, 33, 100, 200, 500] │
└─────────────────────────────────┘

bitmapToArray

将位图转换为整数数组。
语法

bitmapToArray(bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 数组。

类型:array
示例

SELECT bitmapToArray(bitmapBuild([1, 2, 3, 4, 5])) AS res;

结果:

┌─res─────────────┐
│ [1, 2, 3, 4, 5] │
└─────────────────┘

bitmapXor

两个位图进行异或计算,结果是一个新的位图。

bitmapXor(bitmap,bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 位图对象

类型:Bitmap object
示例

SELECT bitmapToArray(bitmapXor(bitmapBuild([1,2,3]),bitmapBuild([3,4,5]))) AS res;

结果:

┌─res──────────┐
│ [1, 2, 4, 5] │
└──────────────┘

bitmapXorCardinality

两个位图进行异或计算,返回 UInt64 类型的基数。
语法

bitmapXorCardinality(bitmap,bitmap)

参数

  • bitmap– 位图对象。

返回值

  • 位图对象

类型:Bitmap object
示例

SELECT bitmapXorCardinality(bitmapBuild([1,2,3]),bitmapBuild([3,4,5])) AS res;

结果:

┌─res─┐
│ 4   │
└─────┘

subBitmap

提取bitmap中指定下标范围的子集数据,从offset位置开始。返回的位图的最大基数是cardinality_limit
语法

subBitmap(bitmap, offset, cardinality_limit)

参数

  • bitmap - [位图对象]
  • offset - 子集中第一个元素的位置,UInt32 类型
  • cardinality_limit - 子集最大基数,UInt32 类型

需要注意,offset从0开始,代表实际存储的第一个有效值,类似于数组下标。offset和 cardinality_limit 超过 bitmap 元素个数均无意义。
返回值

  • 子集

示例

SELECT bitmapToArray(subBitmap(bitmapBuild([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,100,200,500]), toUInt32(10), toUInt32(10))) AS res;

--- 等价于 ByteHouse BitMap64类型如下写法
SELECT bitmapToArray(subBitmap(arrayToBitmap([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 100, 200, 500]), toUInt32(10), toUInt32(10))) AS res
┌─res─────────────────────────────┐
│ [10,11,12,13,14,15,16,17,18,19] │
└─────────────────────────────────┘

聚合函数

下述聚合函数接收多行记录,进行聚合操作,返回一行结果。

序号

函数接口

参数说明

返回值

功能释义

1

bitmapColumnAnd
(bitmap_column)
-> bitmap

BitMap64类型的一列数据

BitMap64对象

接收一个bimap列,该列所有bitmap做运算

2

bitmapColumnOr
(bitmap_column)
-> bitmap

BitMap64类型的一列数据

BitMap64对象

接收一个bimap列,该列所有bitmap做运算

3

bitmapColumnXor
(bitmap_column)
-> bitmap

BitMap64类型的一列数据

BitMap64对象

接收一个bimap列,该列所有bitmap做异或运算

4

bitmapColumnCardinality
(bitmap_column)
-> UInt64

BitMap64类型的一列数据

UInt64数值

接收一个bimap列,该列所有bitmap做运算,返回最终结果bitmap的元素个数

5

bitmapColumnHas
(bitmap_column, integer)
-> bool

BitMap64类型的一列数据
UIntN类型的数字,
N={8, 16, 32, 64}

UInt8枚举
1->true
0->false

接收一个bimap列,检查该列是否包含指定元素

6

bitmapFromColumn(id) -> bitmap

整数列
UIntN类型的数字,
N={8, 16, 32, 64}

BitMap64对象

接收一列整数,聚合成一个bitmap

以下是具体的函数示例:

bitmapColumAnd

计算一列 bitmap 的交集。
语法

bitmapColumnAnd(bitmap_column)

参数
bitmap_column - BitMap64 类型的数据列。
返回值

  • 一个 BitMap64 对象

示例

select bitmapColumnAnd(rbm) as result
from (
    select arrayToBitmap([1,2,3]) as rbm
    union all
    select arrayToBitmap([2,3,4]) as rbm
)

结果:

┌─result─┐
│ {2,3}  │
└────────┘

bitmapColumnOr

计算一列 bitmap 的并集。
语法

bitmapColumnOr(bitmap_column)

参数
bitmap_column - BitMap64 类型的数据列。
返回值

  • 一个 BitMap64 对象

示例

select bitmapColumnOr(rbm) as result
from (
    select arrayToBitmap([1,2,3]) as rbm
    union all
    select arrayToBitmap([2,3,4]) as rbm
)

结果:

┌─result────┐
│ {1,2,3,4} │
└───────────┘

bitmapColumnXor

计算一列 bitmap 的异或集。
语法

bitmapColumnXor(bitmap_column)

参数
bitmap_column - BitMap64 类型的数据列。
返回值

  • 一个 BitMap64 对象

示例

select bitmapColumnXor(rbm) as result
from (
    select arrayToBitmap([1,2,3]) as rbm
    union all
    select arrayToBitmap([2,3,4]) as rbm
)

结果:

┌─result─┐
│ {1,4}  │
└────────┘

bitmapColumnCardinality

计算一列 bitmap 的并集包含的元素个数。
语法

bitmapColumnCardinality(bitmap_column)

参数
bitmap_column - BitMap64 类型的数据列。
返回值

  • 一个UInt64数,表示 bitmap元素个数。

示例

select bitmapColumnCardinality(rbm) as result
from (
    select arrayToBitmap([1,2,3]) as rbm
    union all
    select arrayToBitmap([2,3,4]) as rbm
)

结果:

┌─result─┐
│      4 │
└────────┘

bitmapColumnHas

判断一列 bitmap 中是否包含指定数值。
语法

bitmapColumnHas(bitmap_column, integer_number)

参数
bitmap_column - BitMap64 类型的数据列。
integer_number - 一个常量数值。类型为64位以内的正整数。
返回值

  • 一个Bool 值,0 表示给定数值不存在,1 表示存在。
  • 和函数bitmapContains的区别在于改函数对于一列 bitmap仅返回一行值,bitmapContains则是多行。

示例

select bitmapColumnHas(rbm, 3) as result
from (
    select arrayToBitmap([1,2,3]) as rbm
    union all
    select arrayToBitmap([2,3,4]) as rbm
)

结果:

┌─result─┐
│      1 │
└────────┘

bitmapFromColumn

从一列数值中构建一个BitMap64 对象。
语法

bitmapFromColumn(integer_column)

参数

  • integer_column - 64 位以内的正整数列。

返回值

  • 一个BitMap64 对象

示例

select bitmapFromColumn(number) as res from numbers(10);

结果:

┌─res───────────────────┐
│ {0,1,2,3,4,5,6,7,8,9} │
└───────────────────────┘

高阶聚合函数

这种函数有两个括号传递参数:

  • 第一个括号称为parameter,用于控制聚合函数的行为 (控制流)
  • 第二个括号称为argument,用于向聚合函数传递输入数据列 (数据流)

ByteHouse 提供了一系列聚合函数用于批量处理大量 bitmap 之间的复杂计算。通过给每个待计算的 bitmap编序号,并用序号书写表达出集合的交并差运算,ByteHouse 可以根据指定的运算表达式完成对应的 bitmap 运算,直接把计算可视化和简便化,极大提升了写 SQL的体验!
简单图示如下:

序号

函数接口

参数说明

返回值

功能释义

1

bitmapCount
(expression)
(idx, bitmap)
-> integer

expression是与或差表达式,&表示交集,|表示并集,~表示差集
idx是每行bitmap对应的标记,使用正整数Int16/32类型

UInt64数值

对于bitmap列中的每一行,取其标记idx,存入 map 中。最终依据expression指定的计算方式进行bitmap运算,返回最终bitmap中元素个数

2

bitmapExtract
(idx, bitmap)
-> bitmap

expression是与或差表达式,&表示交集,|表示并集,~表示差集
idx是每行bitmap对应的标记,使用正整数Int16/32类型

BitMap64对象

对于bitmap列中的每一行,取其idx,并依据expression指定的计算方式进行bitmap运算,返回最终计算结果的bitmap

3

bitmapMultiCount
(expr1, expr2, ...)
(idx, bitmap)
-> [int1, int2, ...]

expression是与或差表达式,&表示交集,|表示并集,~表示差集
idx是每行bitmap对应的标记,使用正整数Int16/32类型

UInt64数组

对于bitmap列中的每一行,取其编号 idx,并依据每个expr指定的计算方式进行多组bitmap运算,返回每组expr计算的结果bitmap中元素个数

4

bitmapMultiExtract
(expr1, expr2, ...)
(idx, bitmap)
-> [bitmap1, bitmap2, ...]

expression是与或差表达式,&表示交集,|表示并集,~表示差集
idx是每行bitmap对应的标记,使用正整数Int16/32类型

BitMap64数组

对于bitmap列中的每一行,取其编号 idx,并依据每个expr指定的计算方式进行多组bitmap运算,返回每组expr计算的结果的bitmap数据

5

bitmapMultiCountWithDate
(expr1, expr2, ...)
(date, idx, bitmap)
-> [int1, int2, ...]

expression是与或差表达式,&表示交集,|表示并集,~表示差集
date是Int64类型的日期格式
idx是每行bitmap对应的标记,使用正整数Int16/32类型

UInt64数组

在bitmapMultiCount的基础上增加了日期维度,可以区别出不同日期中的编号。即 bitmapMultiCount 只支持一个编号维度,该函数则额外增加了日期维度。

6

bitmapMultiExtractWithDate
(expr1, expr2, ...)
(date, idx, bitmap)
-> [bitmap1, bitmap2, ...]

expression是与或差表达式,&表示交集,|表示并集,~表示差集
date是Int64类型的日期格式
idx是每行bitmap对应的标记,使用正整数Int16/32类型

BitMap64数组

在bitmapMultiExtract的基础上增加了日期维度,可以区别出不同日期中的标签。即 bitmapMultiExtract 只支持一个编号维度,该函数则额外增加了日期维度。

说明

如果存在相同编号idx的多行数据,聚合函数会自动把多行bitmap通过OR运算合并为一个,参与计算。最终计算时,一个idx对应一个bitmap。

以下是具体的函数说明。

BitmapCount

依据用户指定的计算表达式,执行相应的bitmap运算,返回最终bitmap中元素个数。
语法

BitMapCount(expr)(idx_column, bitmap_column)

参数

  • expr - 使用数字或字符串表示的与(&)、或(|)、差(~)运算,&表示bitmap交集,|表示bitmap并集,~表示bitmap差集,该函数仅支持一个表达式。
  • idx_column - 用于标记 bitmap的数据列,可以是整数列(通常为 Int16/32/64类型),或者字符串列。
  • bitmap_column - BitMap64 数据列。

注1:不要求idx_column数据和bitmap_column数据一一对应,如果idx_column存在重复数据,则值相同的多行 bitmap 会先进行并集运算,合并为一个唯一的 bitmap 参与计算。
注 2:当idx_column列类型位字符串时,不能包含如下保留字符:&, |, ~, ,, #, (, ), _和英文空格。
返回值

  • UInt64 - 计算后的 bitmap 中元素个数。

示例

SELECT bitmapCount('a')(tag_value, uids) AS res
FROM
(
    SELECT
        'a' AS tag_value,
        arrayToBitmap([1, 2, 3]) AS uids
)

结果:

┌─res─┐
│   3 │
└─────┘
SELECT
    BitmapCount('((a&b)|c) ~ d')(tag_value, uids) AS res1,
    BitmapCount('((1&2)|3)~4')(multiIf(tag_value = 'a', toInt16(1), tag_value = 'b', toInt16(2), tag_value = 'c', toInt16(3), tag_value = 'd', toInt16(4), toInt16(0)) AS idx, uids) AS res2
FROM
(
    SELECT
        'a' AS tag_value,
        arrayToBitmap([1, 2, 3, 4, 5]) AS uids
    UNION ALL
    SELECT
        'b' AS tag_value,
        arrayToBitmap([3, 4, 5, 6]) AS uids
    UNION ALL
    SELECT
        'c' AS tag_value,
        arrayToBitmap([5, 7]) AS uids
    UNION ALL
    SELECT
        'd' AS tag_value,
        arrayToBitmap([7]) AS uids
)

结果

┌─res1─┬─res2─┐
│    3 │    3 │
└──────┴──────┘

BitmapExtract

依据用户指定的计算表达式,执行相应的bitmap运算,返回最终bitmap。
语法

BitMapExtract(expr)(idx_column, bitmap_column)

参数

  • expr - 使用数字或字符串表示的与(&)、或(|)、差(~)运算,&表示bitmap交集,|表示bitmap并集,~表示bitmap差集,该函数仅支持一个表达式。
  • idx_column - 用于标记 bitmap的数据列,可以是整数列(通常为 Int16/32/64类型),或者字符串列。
  • bitmap_column - BitMap64 数据列。

注意

  • 不要求idx_column数据和bitmap_column数据一一对应,如果idx_column存在重复数据,则值相同的多行 bitmap 会先进行并集运算,合并为一个唯一的 bitmap 参与计算。
  • idx_column列类型位字符串时,不能包含如下保留字符:&, |, ~, ,, #, (, ), _和英文空格。

返回值

  • BitMap64 - 计算后的 bitmap 对象。

示例

SELECT bitmapExtract('a')(tag_value, uids) AS res
FROM
(
    SELECT
        'a' AS tag_value,
        arrayToBitmap([1, 2, 3]) AS uids
)

结果

┌─res─────┐
│ {1,2,3} │
└─────────┘
SELECT
    BitmapExtract('((a&b)|c) ~ d')(tag_value, uids) AS res1,
    BitmapExtract('((1&2)|3)~4')(multiIf(tag_value = 'a', toInt16(1), tag_value = 'b', toInt16(2), tag_value = 'c', toInt16(3), tag_value = 'd', toInt16(4), toInt16(0)) AS idx, uids) AS res2
FROM
(
    SELECT
        'a' AS tag_value,
        arrayToBitmap([1, 2, 3, 4, 5]) AS uids
    UNION ALL
    SELECT
        'b' AS tag_value,
        arrayToBitmap([3, 4, 5, 6]) AS uids
    UNION ALL
    SELECT
        'c' AS tag_value,
        arrayToBitmap([5, 7]) AS uids
    UNION ALL
    SELECT
        'd' AS tag_value,
        arrayToBitmap([7]) AS uids
)

结果:

┌─res1────┬─res2────┐
│ {3,4,5} │ {3,4,5} │
└─────────┴─────────┘

BitmapMultiCount

依据用户指定的一组计算表达式,每组执行相应的bitmap运算,返回每组最终bitmap中元素个数。
语法

BitmapMultiCount(expr1, expr2, expr3,...)(idx_column, bitmap_column)

参数

  • expr - 使用数字或字符串表示的与(&)、或(|)、差(~)运算,&表示bitmap交集,|表示bitmap并集,~表示bitmap差集,该函数支持多个表达式。
  • idx_column - 用于标记 bitmap的数据列,可以是整数列(通常为 Int16/32/64类型),或者字符串列。
  • bitmap_column - BitMap64 数据列。

注意

  • 不要求idx_column数据和bitmap_column数据一一对应,如果idx_column存在重复数据,则值相同的多行 bitmap 会先进行并集运算,合并为一个唯一的 bitmap 参与计算。
  • idx_column列类型位字符串时,不能包含如下保留字符:&, |, ~, ,, #, (, ), _和英文空格。
  • 支持结果复用。比如 expr1='a&b', expr2='(a&b)|c。那么可以简化 expr2 的写法为expr2='_1|c'。使用下划线+数字可以指定某个已经出现过的表达式,可以简化复杂表达式写法。

返回值

  • UInt64数组 - 每个表达式计算后的 bitmap 中元素个数。数组大小和表达式个数相等。

示例

SELECT BitmapMultiCount('a')(tag_value, uids) AS res
FROM
(
    SELECT
        'a' AS tag_value,
        arrayToBitmap([1, 2, 3]) AS uids
)
┌─res─┐
│ [3] │
└─────┘
SELECT BitmapMultiCount('1&2', '(1&2)|3', '_1|3', '((1&2)|3) ~ 4', '_2~4')(tag_value, uids) AS res
FROM
(
    SELECT
        toInt32(1) AS tag_value,
        arrayToBitmap([1, 2, 3, 4, 5]) AS uids
    UNION ALL
    SELECT
        toInt32(2) AS tag_value,
        arrayToBitmap([3, 4, 5, 6]) AS uids
    UNION ALL
    SELECT
        toInt32(3) AS tag_value,
        arrayToBitmap([5, 7]) AS uids
    UNION ALL
    SELECT
        toInt32(4) AS tag_value,
        arrayToBitmap([7]) AS uids
)

结果:

┌─res─────────┐
│ [3,4,4,3,3] │
└─────────────┘

BitmapMultiExtract

依据用户指定的一组计算表达式,每组执行相应的bitmap运算,返回每组最终bitmap。
语法

BitmapMultiExtract(expr1, expr2, expr3,...)(idx_column, bitmap_column)

参数

  • expr - 使用数字或字符串表示的与(&)、或(|)、差(~)运算,&表示bitmap交集,|表示bitmap并集,~表示bitmap差集,该函数支持多个表达式。
  • idx_column - 用于标记 bitmap的数据列,可以是整数列(通常为 Int16/32/64类型),或者字符串列。
  • bitmap_column - BitMap64 数据列。

注意

  • 不要求idx_column数据和bitmap_column数据一一对应,如果idx_column存在重复数据,则值相同的多行 bitmap 会先进行并集运算,合并为一个唯一的 bitmap 参与计算。
  • idx_column列类型位字符串时,不能包含如下保留字符:&, |, ~, ,, #, (, ), _和英文空格。
  • 支持结果复用。比如 expr1='a&b', expr2='(a&b)|c。那么可以简化 expr2 的写法为expr2='_1|c'。使用下划线+数字可以指定某个已经出现过的表达式,可以简化复杂表达式写法。

返回值

  • BitMap64数组 - 每个表达式计算后的 bitmap,数组大小和表达式个数相等。

示例

SELECT BitmapMultiExtract('a')(tag_value, uids) AS res
FROM
(
    SELECT
        'a' AS tag_value,
        arrayToBitmap([1, 2, 3]) AS uids
)
┌─res───────┐
│ [{1,2,3}] │
└───────────┘
SELECT BitmapMultiExtract('1&2', '(1&2)|3', '_1|3', '((1&2)|3) ~ 4', '_2~4')(tag_value, uids) AS res
FROM
(
    SELECT
        toInt32(1) AS tag_value,
        arrayToBitmap([1, 2, 3, 4, 5]) AS uids
    UNION ALL
    SELECT
        toInt32(2) AS tag_value,
        arrayToBitmap([3, 4, 5, 6]) AS uids
    UNION ALL
    SELECT
        toInt32(3) AS tag_value,
        arrayToBitmap([5, 7]) AS uids
    UNION ALL
    SELECT
        toInt32(4) AS tag_value,
        arrayToBitmap([7]) AS uids
)

结果:

┌─res───────────────────────────────────────────┐
│ [{3,4,5},{3,4,5,7},{3,4,5,7},{3,4,5},{3,4,5}] │
└───────────────────────────────────────────────┘

BitmapMultiCountWithDate

依据用户指定的一组计算表达式,每组执行相应的bitmap运算,返回每组最终bitmap中元素个数。相比函数BitmapMultiCount多了一个日期表示维度。
语法

BitmapMultiCountWithDate(expr1, expr2, expr3,...)(date_column, idx_column, bitmap_column)

参数

  • expr - 使用数字或字符串表示的与(&)、或(|)、差(~)运算,&表示bitmap交集,|表示bitmap并集,~表示bitmap差集,该函数支持多个表达式,需要注意每个表达式由两部分组成:一部分是日期,一部分是标记,并使用下划线连接,示例为20240101_aaa&20240102_aaa
  • date_colulmn - 用于指定数据日期,需要时 Int64 类型表示的日期列,格式为 YYYYMMDD。
  • idx_column - 用于标记 bitmap的数据列,可以是整数列(通常为 Int16/32/64类型),或者字符串列。
  • bitmap_column - BitMap64 数据列。

注意

  • 不要求date_column+idx_column数据和bitmap_column数据一一对应,如果date_column+idx_column存在重复数据,则值相同的多行 bitmap 会先进行并集运算,合并为一个唯一的 bitmap 参与计算。
  • idx_column列类型位字符串时,不能包含如下保留字符:&, |, ~, ,, #, (, ), _和英文空格。
  • 支持结果复用。比如 expr1='a&b', expr2='(a&b)|c。那么可以简化 expr2 的写法为expr2='_1|c'。使用下划线+数字可以指定某个已经出现过的表达式,可以简化复杂表达式写法。

返回值

  • UInt64数组 - 每个表达式计算后的 bitmap 中元素个数。数组大小和表达式个数相等。

示例

SELECT BitmapMultiCountWithDate('20240102_a~20240101_a', '20240101_a&20240102_a')(toInt64(toYYYYMMDD(date)), tag_value, uids) AS res
FROM
(
    SELECT
        'a' AS tag_value,
        '2024-01-01' AS date,
        arrayToBitmap([1, 2, 3]) AS uids
    UNION ALL
    SELECT
        'a' AS tag_value,
        '2024-01-02' AS date,
        arrayToBitmap([2, 3, 4, 5, 6]) AS uids
)
┌─res───┐
│ [3,2] │
└───────┘
SELECT BitmapMultiCountWithDate('20240101_1 & 20240102_2', '_1 | 20240101_3', '_2 ~ 20240101_4')(toInt64(toYYYYMMDD(date)), tag_value, uids) AS res
FROM
(
    SELECT
        toInt32(1) AS tag_value,
        '2024-01-01' AS date,
        arrayToBitmap([1, 2, 3, 4, 5]) AS uids
    UNION ALL
    SELECT
        toInt32(2) AS tag_value,
        '2024-01-02' AS date,
        arrayToBitmap([3, 4, 5, 6]) AS uids
    UNION ALL
    SELECT
        toInt32(3) AS tag_value,
        '2024-01-01' AS date,
        arrayToBitmap([5, 7]) AS uids
    UNION ALL
    SELECT
        toInt32(4) AS tag_value,
        '2024-01-01' AS date,
        arrayToBitmap([7]) AS uids
)

结果:

┌─res─────┐
│ [3,4,3] │
└─────────┘

BitmapMultiExtractWithDate

依据用户指定的一组计算表达式,每组执行相应的bitmap运算,返回每组最终bitmap。相比函数BitmapMultiExtract多了一个日期表示维度。
语法

BitmapMultiExtractWithDate(expr1, expr2, expr3,...)(date_column, idx_column, bitmap_column)

参数

  • expr - 使用数字或字符串表示的与(&)、或(|)、差(~)运算,&表示bitmap交集,|表示bitmap并集,~表示bitmap差集,该函数支持多个表达式,需要注意每个表达式由两部分组成:一部分是日期,一部分是标记,并使用下划线连接,示例为20240101_aaa&20240102_aaa
  • date_colulmn - 用于指定数据日期,需要时 Int64 类型表示的日期列,格式为 YYYYMMDD。
  • idx_column - 用于标记 bitmap的数据列,可以是整数列(通常为 Int16/32/64类型),或者字符串列。
  • bitmap_column - BitMap64 数据列。

注意

  • 不要求date_column+idx_column数据和bitmap_column数据一一对应,如果date_column+idx_column存在重复数据,则值相同的多行 bitmap 会先进行并集运算,合并为一个唯一的 bitmap 参与计算。
  • idx_column列类型位字符串时,不能包含如下保留字符:&, |, ~, ,, #, (, ), _和英文空格。
  • 支持结果复用。比如 expr1='a&b', expr2='(a&b)|c。那么可以简化 expr2 的写法为expr2='_1|c'。使用下划线+数字可以指定某个已经出现过的表达式,可以简化复杂表达式写法。

返回值

  • BitMap64数组 - 每个表达式计算后的 bitmap,数组大小和表达式个数相等。

示例

SELECT BitmapMultiExtractWithDate('20240102_a~20240101_a', '20240101_a&20240102_a')(toInt64(toYYYYMMDD(date)), tag_value, uids) AS res
FROM
(
    SELECT
        'a' AS tag_value,
        '2024-01-01' AS date,
        arrayToBitmap([1, 2, 3]) AS uids
    UNION ALL
    SELECT
        'a' AS tag_value,
        '2024-01-02' AS date,
        arrayToBitmap([2, 3, 4, 5, 6]) AS uids
)
┌─res─────────────┐
│ [{4,5,6},{2,3}] │
└─────────────────┘
SELECT BitmapMultiExtractWithDate('20240101_1 & 20240102_2', '_1 | 20240101_3', '_2 ~ 20240101_4')(toInt64(toYYYYMMDD(date)), tag_value, uids) AS res
FROM
(
    SELECT
        toInt32(1) AS tag_value,
        '2024-01-01' AS date,
        arrayToBitmap([1, 2, 3, 4, 5]) AS uids
    UNION ALL
    SELECT
        toInt32(2) AS tag_value,
        '2024-01-02' AS date,
        arrayToBitmap([3, 4, 5, 6]) AS uids
    UNION ALL
    SELECT
        toInt32(3) AS tag_value,
        '2024-01-01' AS date,
        arrayToBitmap([5, 7]) AS uids
    UNION ALL
    SELECT
        toInt32(4) AS tag_value,
        '2024-01-01' AS date,
        arrayToBitmap([7]) AS uids
)

结果:

┌─res─────────────────────────┐
│ [{3,4,5},{3,4,5,7},{3,4,5}] │
└─────────────────────────────┘

其他函数与操作接口

BitEngine场景编解码函数

No.

Function interface

Parameter description

Return value

Brief explanation

1

EncodeNonBitEngineColumn(UInt64_column, database, table, dictionary,add_new_key_to_bitengine_dict)
-> UInt64
最后一个参数是新增的可选参数。没有就是默认值0,如果需要则必须带上,且赋值为1

UInt64_column:
source input;
Database, table, dictionary: 指明使用的字典来源,字符串
add_new_key_to_bitengine_dict,如何处理字典不存在的id? 加入字典还是丢弃?

UInt64 value

用普通的UInt64作为 BitEngine K-V dictionary中的K,以获取该值经过字典编码之后的值
新增:
add_new_key_to_bitengine_dict控制如何处理新出现的id:
0:默认行为,可不传,不加入字典;
1:新增行为,必须带上,字典编码时遇到新的id就加入字典当中。

2

DecodeNonBitEngineColumn(UInt64_column, database, table, dictionary)
-> UInt64

UInt64_column:
source input;
Database, table, dictionary: 指明使用的字典来源,字符串

UInt64 value

用普通的UInt64作为 BitEngine K-V dictionary中的V,以获取该值在字典编码之前的值

3

EncodeBitmap(bitmap, database, table, dictionary, add_new_key_to_bitengine_dict)
-> BitMap64
最后一个参数是新增的可选参数。没有就是默认值0,如果需要则必须带上,且赋值为1

bitmap: source input;
Database, table, dictionary: 指明使用的字典来源,字符串

BitMap64 object

使用BitEngine dictionary来对一个bitmap做编码操作
新增:
add_new_key_to_bitengine_dict控制如何处理新出现的id:
0:默认行为,可不传,不加入字典;
1:新增行为,必须带上,字典编码时遇到新的id就加入字典当中。

4

DecodeBitmap(bitmap, database, table, dictionary)
->BitMap64

bitmap: source input;
Database, table, dictionary: strings identify the dictionary source

BitMap64 object

使用BitEngine dictionary来对一个bitmap做解码操作

5

arrayToBitmapWithEncode
([x1,...], 'db', 'tbl', 'dict_name',
add_new_key_to_bitengine_dict)
-> bitmap

最后一个参数是新增的可选参数。没有就是默认值0,如果需要则必须带上,且赋值为1

UIntN类型的数组,
N={8, 16, 32, 64},
db,tbl,dict_name分别对应库、表、列
add_new_key_to_bitengine_dict控制字典如何处理新出现的id?加入字典或者丢弃

BitMap64对象

利用已存在的BitEngine字典给新的bitmap编码,返回编码后的bitmap
新增:
add_new_key_to_bitengine_dict控制如何处理新出现的id:
0:默认行为,可不传,不加入字典;
1:新增行为,必须带上,字典编码时遇到新的id就加入字典当中。

6

bitmapToArrayWithDecode(bitmap, 'db', 'tbl', 'dict_name')
-> array

bitmap: source input;
Database, table, dictionary: strings identify the dictionary source

Array(UInt64)

解码bitmap,同时将bitmap转为数组

替换社区BitMap函数

如果您此前使用了社区的BitMap函数,当前希望迁移至ByteHouse,可参考如下规则替换社区的BitMap函数。

注意

ClickHouse/ByteHouse 是支持聚合函数组合算子,详见Aggregate Function Combinators,其使用格式是【聚合函数名】+【Combinator】,常见的 Combinator 如 -If-State。如groupBitmapOrStategroupBitmapOrStateIf,替换函数时,只需要考虑groupBitmapOr函数名就行,Combinator 部分不变。
常见 Combinator 的替换规则:

  • -State:直接去掉
  • -If :保留
  • -Merge:直接去掉

示例:
groupBitmapStateIf -> bitmapFromColumnIf
groupBitmapOrState -> bitmapColumnOr

ByteHouse 适配以及支持了所有 ClickHouse 社区的 bitmap 函数,其映射关系如下:

ClickHouse 社区函数名

ByteHouse 对等实现

示例

bitmapBuild

arrayToBitmap

示例:select arrayToBitmap([1,2,3])

bitmapToArray

bitmapToArray

示例:select bitmapToArray(arrayToBitmap([1,2,3]))

bitmapSubsetInRange

bitmapSubsetInRange

示例:select bitmapSubsetInRange(arrayToBitmap([1,2,3]), 1, 2)

bitmapSubsetLimit

bitmapSubsetLimit

示例:select bitmapSubsetLimit(arrayToBitmap([1,2,3]), 1, 1)

subBitmap

subBitmap

示例:select subBitmap(arrayToBitmap([1,2,3]), 2, 2)

bitmapContains

bitmapContains

示例:select bitmapContains(arrayToBitmap([1,2,3]), 2)

bitmapHasAny

bitmapHasAny

示例:select bitmapHasAny(arrayToBitmap([1,2,3]), arrayToBitmap([2,3]))

bitmapHasAll

bitmapHasAll

示例:select bitmapHasAll(arrayToBitmap([1,2,3]), arrayToBitmap([2,3]))

bitmapCardinality

bitmapCardinality

示例:select bitmapCardinality(arrayToBitmap([1,2,3]))

bitmapMin

bitmapMin

示例:select bitmapMin(arrayToBitmap([1,2,3]))

bitmapMax

bitmapMax

示例:select bitmapMax(arrayToBitmap([1,2,3]))

bitmapTransform

bitmapTransform

示例:select bitmapTransform(arrayToBitmap([1,2,3]), [2,3], [3,4])

bitmapAnd

bitmapAnd

示例:select bitmapAnd(arrayToBitmap([1,2,3]), arrayToBitmap([2,3]))

bitmapOr

bitmapOr

示例:select bitmapOr(arrayToBitmap([1,2,3]), arrayToBitmap([2,3]))

bitmapXor

bitmapXor

示例:select bitmapXor(arrayToBitmap([1,2,3]), arrayToBitmap([2,3]))

bitmapAndnot

bitmapAndnot

示例:select bitmapAndnot(arrayToBitmap([1,2,3]), arrayToBitmap([2,3]))

bitmapAndCardinality

bitmapAndCardinality

示例:select bitmapAndCardinality(arrayToBitmap([1,2,3]), arrayToBitmap([2,3]))

bitmapOrCardinality

bitmapOrCardinality

示例:select bitmapOrCardinality(arrayToBitmap([1,2,3]), arrayToBitmap([2,3]))

bitmapXorCardinality

bitmapXorCardinality

示例:select bitmapXorCardinality(arrayToBitmap([1,2,3]), arrayToBitmap([2,3]))

bitmapAndnotCardinality

bitmapAndnotCardinality

示例:select bitmapAndnotCardinality(arrayToBitmap([1,2,3]), arrayToBitmap([2,3]))

groupBitmap

bitmapCardinality(bitmapFromColumn(number))

示例:select bitmapCardinality(bitmapFromColumn(number)) from numbers(10);

groupBitmapState

bitmapFromColumn

示例:select bitmapFromColumn(number) from numbers(10);

groupBitmapOr

bitmapColumnCardinality

示例: select bitmapColumnCardinality(rbm) from (select bitmapFromColumn(number) as rbm from numbers(10));

groupBitmapOrState

bitmapColumnOr

示例:select bitmapColumnOr(rbm) from (select bitmapFromColumn(number) as rbm from numbers(10));

groupBitmapAnd

bitmapCardinality(bitmapColumnAnd(bitmap_column))

示例:select bitmapCardinality(bitmapColumnAnd(rbm)) from (select bitmapFromColumn(number) as rbm from numbers(10));

groupBitmapAndState

bitmapColumnAnd

示例:select bitmapColumnAnd(rbm) from (select bitmapFromColumn(number) as rbm from numbers(10));

groupBitmapXor

bitmapCardinality(bitmapColumnXor(bitmap_column))

示例:select bitmapCardinality(bitmapColumnXor(rbm)) from (select bitmapFromColumn(number) as rbm from numbers(10));

groupBitmapXorState

bitmapColumnXor

示例:select bitmapColumnXor(rbm) from (select bitmapFromColumn(number) as rbm from numbers(10));

函数使用示例

建测试表

示例用表 test.bitmap_test。

CREATE TABLE test.bitmap_test (
    `p_date` Date, 
    `slice_id` UInt64,
    `tag_id` Int32,
    `tag_value` String, 
    `uids` BitMap64
) ENGINE = CnchMergeTree 
PARTITION BY p_date
ORDER BY (tag_id, tag_value)
SETTINGS index_granularity = 128;

写入数据

数据涉及两个标签,tag_id=11,有两个标签值'a'和'b';tag_id=12,有一个标签值'c'。
每个标签值有两行,其 slice_id 不一样。slice_id 是为了把大 bitmap 进行切分,减小每行 bitmap量级,可优化构建效率和内存使用量,同时也能够为分布式存储提供分片凭据。

insert into test.bitmap_test values ('2024-01-01', 0, 11, 'a', [1,2,3,4,5]), ('2024-01-02', 1, 11,'a', [11,12,13,14,15]);
insert into test.bitmap_test values ('2024-01-01', 0, 11, 'b', [3,4,5,6,7,8]), ('2024-01-02', 1, 11,'b', [13, 14,15,16]);
insert into test.bitmap_test values ('2024-01-01', 0, 12, 'c', [3,4,6,7,9]), ('2024-01-02', 1, 12,'c', [13,15,16,18]);

示例:普通函数

普通函数的使用和社区demo,以及其它函数并无差异。仅举几个例子。

数组转bitmap

SELECT arrayToBitmap([1, 2, 3, 4, 5])
FORMAT TSV

-- 结果:
{1,2,3,4,5}

bitmap转数组

SELECT bitmapToArray(uids)
FROM test.bitmap_test
WHERE tag_value = 'a'
FORMAT TSV

-- 结果:
[11,12,13,14,15]
[1,2,3,4,5]


SELECT bitmapToArray(arrayToBitmap([1, 2, 3, 4, 5]))
FORMAT TSV

-- 结果:
[1,2,3,4,5]

求bitmap中的元素个数

SELECT bitmapCardinality(arrayToBitmap([1, 2, 3, 4, 5]))
FORMAT TSV

-- 结果:
5

示例:聚合函数

多个bitmap的交/并/异或运算

-- 求两个 bitmap 的交集
SELECT bitmapColumnAnd(uids)
FROM test.bitmap_test
WHERE (slice_id = 0) AND (tag_value IN ('a', 'b'))
FORMAT TSV

-- 结果:
{3,4,5}

-- 求两个 bitmap 的并集(两个函数同义)
SELECT
    bitmapCardinality(bitmapColumnOr(uids)),
    bitmapColumnCardinality(uids)
FROM test.bitmap_test
WHERE (slice_id = 0) AND (tag_value IN ('a', 'b'))
FORMAT TSV

-- 结果:
8        8

-- 判断某个 bitmap中是否存在给定元素
SELECT bitmapColumnHas(uids, 12)
FROM test.bitmap_test
WHERE tag_value = 'a'
FORMAT TSV

-- 结果:
1

聚合一个bitmap

SELECT bitmapFromColumn(number)
FROM
(
    SELECT number
    FROM system.numbers
    LIMIT 100, 10
)
FORMAT TSV

-- 结果
{100,101,102,103,104,105,106,107,108,109}

bitmapCount函数

用途:​实现多个bitmap之间的复杂交并差运算。用户通过输入表达式表示出 bitmap 的运算,函数解析后进行对应计算。示例参考上文【聚合函数】- 【高阶聚合函数】小节的图例。
输入:​编号列,bitmap列。编号列用于标识 bitmap,可以是表中字段(如 tag_id),也可以是人为定义变量(如 idx)。
表达式:​一个编号锚定一个 bitmap。编号表达式是与或差操作,对应 bitmap的交并差运算。
支持的编号运算符:

  • 或操作:使用逗号('1,2')或者竖线('1|2')表示
  • 与操作:使用&表示('1&2')
  • 差集操作:使用表示('12')

输出:​bitmap 交并差运算之后的结果 bitmap 中的元素个数。

Case 1: 求某个标签'a'总共元素个数:

SELECT bitmapColumnCardinality(uids)
FROM test.bitmap_test
WHERE tag_value = 'a'
FORMAT TSV

-- 结果:
10

-- 求标签'a'总共元素个数。等同于bitmapColumnCardinality的计算
SELECT bitmapCount('1')(If(tag_value = 'a', toInt32(1), toInt32(999)) AS idx, uids) AS card
FROM test.bitmap_test
WHERE tag_value = 'a'
FORMAT TSV

-- 结果:
10

-- 求标签'a'总共元素个数,标签为字符串,可以直接用字符串表达式
SELECT bitmapCount('a')(tag_value, uids)
FROM test.bitmap_test
WHERE tag_value = 'a'
FORMAT TSV

-- 结果:
10

Case 2: 求两个标签的交集'a'和'b'

SELECT bitmapCardinality(bitmapColumnAnd(uids)) AS card
FROM test.bitmap_test
WHERE (tag_value IN ('a', 'b')) AND (slice_id = 0)
FORMAT CSV

-- 结果:
10

-- 等同于bitmapCardinality(bitmapColumnAnd)的计算
SELECT bitmapCount('1&2')(multiIf(tag_value = 'a', toInt32(1), tag_value = 'b', 2, toInt32(999)) AS idx, uids) AS card
FROM test.bitmap_test
WHERE (tag_value IN ('a', 'b')) AND (slice_id = 0)
FORMAT TSV

-- 结果:
3

-- 上述sql的另一种写法,适合复杂sql嵌套
SELECT bitmapCount('1&2')(idx, uids)
FROM
(
    SELECT
        toInt32(1) AS idx,
        uids
    FROM test.bitmap_test
    WHERE (slice_id = 0) AND (tag_value IN ('a'))
    UNION ALL
    SELECT
        toInt32(2) AS idx,
        uids
    FROM test.bitmap_test
    WHERE (slice_id = 0) AND (tag_value IN ('b'))
)
FORMAT TSV

-- 结果:
3

Case 3: 更多标签的交并差运算

-- 写法一
SELECT bitmapCount('1&2|3')(multiIf(tag_value = 'a', toInt32(1), tag_value = 'b', toInt32(2), tag_value = 'c', toInt32(3), toInt32(999)) AS idx, uids) AS card
FROM test.bitmap_test
FORMAT TSV

-- 结果:
11

-- 写法二:刚好 tag_value是字符串类型,可以使用字符串表达式
SELECT bitmapCount('a&b|c')(tag_value, uids)
FROM test.bitmap_test
FORMAT TSV

-- 结果:
11

bitmapExtract

这个函数计算方法和bitmapCount是一样的,区别是它返回计算结果的bitmap, 不是个数。
至于怎么组合标签,等同于bitmapCount函数。bitmapCount 那里使用的是 tag_value 作为示例,这里展示一个 tag_id 作为示例的 case: 求两个标签的交集:

SELECT bitmapExtract('1&2')(multiIf(tag_id = 11, toInt32(1), tag_id = 12, 2, toInt32(999)) AS idx, uids) AS card
FROM test.bitmap_test
WHERE (tag_id IN (1,2)) AND (slice_id = 0)
FORMAT TSV

-- 结果(没有交集):
{}

另一种写法:
SELECT bitmapExtract('11&12')(tag_id, uids)
FROM test.bitmap_test
WHERE (tag_id IN (1, 2)) AND (slice_id = 0)
FORMAT TSV

-- 结果(没有交集):
{}

bitmapMultiCount函数

这个聚合函数再bitmapCount的基础上,支持了多组表达式
用途:​实现多个bitmap之间的复杂交并差运算,同时支持了多组运算和运算复用。用户通过输入表达式表示出 bitmap 的运算,函数解析后进行对应计算。示例参考上文【聚合函数】- 【高阶聚合函数】小节的图例。
输入:​编号列,bitmap列。编号列用于标识 bitmap,可以是表中字段(如 tag_id),也可以是人为定义变量(如 idx)。
表达式:​一个编号锚定一个 bitmap。编号表达式是与或差操作,对应 bitmap的交并差运算。同时可以提供多组表达式,函数依次执行对应计算,把多组结果一并返回。
支持的编号运算符:

  • 或操作:使用逗号('1,2')或者竖线('1|2')表示
  • 与操作:使用&表示('1&2')
  • 差集操作:使用表示('12')
  • 表达式复用:通过下划线+位置数字的方式复用某一个表达式的结果。如"_3"表示复用第三个表达式(从一开始数)

输出:​bitmap 交并差运算之后的结果 bitmap 中的元素个数。每个表达式对应一个结果,存储在数组中。

-- '_3|3'等价于 '(1&2)|3'
SELECT bitmapMultiCount('1', '2', '1&2', '_3|3')(multiIf(tag_value = 'a', toInt32(1), tag_value = 'b', toInt32(2), tag_value = 'c', toInt32(3), toInt32(999)) AS idx, uids) AS card
FROM test.bitmap_test
WHERE slice_id = 0
FORMAT TSV

-- 结果:
[5,6,3,6]

-- tag_value 刚好是字符串类型,所以也可以使用字符串表达式
SELECT bitmapMultiCount('a', 'b', 'a&b', '_3|c')(tag_value, uids) AS card
FROM test.bitmap_test
WHERE slice_id = 0
FORMAT TSV

-- 结果:
[5,6,3,6]

_3表示复用了位置3处的表达式,即'1&2'。
有一组集合关系可以验证是否正确。该关系是
A + B = AUB + A交B

SELECT bitmapMultiCount('1', '2', '1&2', '1|2')(multiIf(tag_value = 'a', toInt32(1), tag_value = 'b', toInt32(2), tag_value = 'c', toInt32(3), toInt32(999)) AS idx, uids) AS card
FROM test.bitmap_test
WHERE slice_id = 0
FORMAT TSV

-- 结果:
[5,6,3,8]

-- tag_value 刚好是字符串类型,所以也可以使用字符串表达式
SELECT bitmapMultiCount('a', 'b', 'a&b', 'a|b')(tag_value, uids)
FROM test.bitmap_test
WHERE slice_id = 0
FORMAT TSV

-- 结果:
[5,6,3,8]

bitmapMultiExtract

含义用户同bitmapMultiCount,差异点在返回值,返回 bitmap 数据。

SELECT bitmapMultiExtract('1', '2', '1&2', '1|2')(multiIf(tag_value = 'a', toInt32(1), tag_value = 'b', toInt32(2), tag_value = 'c', toInt32(3), toInt32(999)) AS idx, uids) AS card
FROM test.bitmap_test
WHERE slice_id = 0
FORMAT TSV

[{1,2,3,4,5},{3,4,5,6,7,8},{3,4,5},{1,2,3,4,5,6,7,8}]

-- tag_value 刚好是字符串类型,所以也可以使用字符串表达式
SELECT bitmapMultiExtract('a', 'b', 'a&b', 'a|b')(tag_value, uids)
FROM test.bitmap_test
WHERE slice_id = 0
FORMAT TSV

-- 结果:
[{1,2,3,4,5},{3,4,5,6,7,8},{3,4,5},{1,2,3,4,5,6,7,8}]

bitmapMultiCountWithDate

用途:​这个函数在bitmapMultiCount的基础上又加入了日期维度,可以在表达式中区别不同日期的标签。
注意日期列需要是 Int64 类型,一般日期用 Date类型,需要使用 toYYYYMMDD 函数进行转换。
输入:​日期列,编号列,bitmap 列。
表达式:​一个日期和一个编号组合锚定一个 bitmap,无法单独使用。所以日期_编号作为整体使用,如示例中的'20240101_1' 才能标识一个 bitmap。上文的函数bitmapMultiCount只需要'1'就可以,这是两者的差异点。
输出:​bitmap 交并差运算之后的结果 bitmap 中的元素个数。每个表达式对应一个结果,存储在数组中。

SELECT bitmapMultiCountWithDate('20240101_1', '20240102_2', '20240101_1|20240102_2')(CAST(toYYYYMMDD(p_date), 'Int64') AS date1, multiIf((tag_value = 'a') AND (p_date = '2024-01-01'), toInt64(1), (tag_value = 'b') AND (p_date = '2024-01-02'), toInt64(2), (tag_value = 'c') and (p_date = '2024-01-01'), toInt64(3),toInt32(999)) AS idx, uids) AS card
FROM test.bitmap_test
FORMAT TSV

-- 结果:
[5,4,9]

-- tag_value刚好是字符串类型,所以可以使用字符串表达式
SELECT bitmapMultiCountWithDate('20240101_a', '20240102_b', '20240101_a|20240102_b')(CAST(toYYYYMMDD(p_date), 'Int64') AS date1, tag_value, uids) AS card
FROM test.bitmap_test
FORMAT TSV

-- 结果:
[5,4,9]

bitmapMultiExtractWithDate

功能和用法同bitmapMultiCountWithDate,差异点在返回值,返回 bitmap 数据。

SELECT bitmapMultiExtractWithDate('20240101_1', '20240102_2', '20240101_1|20240102_2')(CAST(toYYYYMMDD(p_date), 'Int64') AS date1, multiIf((tag_value = 'a') AND (p_date = '2024-01-01'), toInt64(1), (tag_value = 'b') AND (p_date = '2024-01-02'), toInt64(2), (tag_value = 'c') and (p_date = '2024-01-01'), toInt64(3),toInt32(999)) AS idx, uids) AS card
FROM test.bitmap_test
FORMAT TSV

-- 结果:
[{1,2,3,4,5},{13,14,15,16},{1,2,3,4,5,13,14,15,16}]


-- tag_value刚好是字符串类型,所以可以使用字符串表达式
SELECT bitmapMultiExtractWithDate('20240101_a', '20240102_b', '20240101_a|20240102_b')(CAST(toYYYYMMDD(p_date), 'Int64') AS date1, tag_value, uids) AS card
FROM test.bitmap_test
FORMAT TSV

-- 结果:
[{1,2,3,4,5},{13,14,15,16},{1,2,3,4,5,13,14,15,16}]
最近更新时间:2026.01.22 15:48:13
这个页面对您有帮助吗?
有用
有用
无用
无用