如何在 clickhouse 中使用 groupBitmapAnd 和 AggregatingMergeTree 引擎?

Posted

技术标签:

【中文标题】如何在 clickhouse 中使用 groupBitmapAnd 和 AggregatingMergeTree 引擎?【英文标题】:How can i use groupBitmapAnd with AggregatingMergeTree engine in clickhouse? 【发布时间】:2021-07-13 07:24:47 【问题描述】:

我想在 clickhouse 中维护一个表,它使用位图“AND”逻辑来合并具有相同 tag_id 行的位图。

由于位图在 clickhouse 中定义为 AggregateFunction(groupBitmap, UInt*) 并且 groupBitmapAnd 将位图作为其参数,因此我创建了一个如下表:

CREATE TABLE test.bitmap_column_expr_test2
(
    `tag_id` String,
    `z` AggregateFunction(groupBitmapAnd, AggregateFunction(groupBitmap, UInt32))
)
ENGINE = AggregatingMergeTree()
ORDER BY tag_id
SETTINGS index_granularity = 8192

就我而言,我想插入如下数据:

INSERT INTO test.bitmap_column_expr_test2 VALUES ('tag1', groupBitmapAndState(bitmapBuild(cast([1,2,3,4] as Array(UInt32)))));
INSERT INTO test.bitmap_column_expr_test2 VALUES ('tag1', groupBitmapAndState(bitmapBuild(cast([1] as Array(UInt32)))));
INSERT INTO test.bitmap_column_expr_test2 VALUES ('tag1', groupBitmapAndState(bitmapBuild(cast([1,3,4] as Array(UInt32)))));

我希望通过以下方式获得位图和结果:

SELECT bitmapToArray(groupBitmapAndMergeState(z)) FROM test.bitmap_column_expr_test2;

但是,我的 ddl 被 clickhouse 重写为:

CREATE TABLE test.bitmap_column_expr_test2
(
    `tag_id` String,
    `z` AggregateFunction(groupBitmap, AggregateFunction(groupBitmap, UInt32))
)
ENGINE = AggregatingMergeTree()
ORDER BY tag_id

丢失了列z的原始定义

此外,插入最终会出现异常:

DB::Exception: Aggregate function groupBitmapAndState(bitmapBuild(CAST([1, 2, 3, 4], 'Array(UInt32)'))) is found in wrong place in query: While processing groupBitmapAndState(bitmapBuild(CAST([1, 2, 3, 4], 'Array(UInt32)'))) (version 20.11.4.13 (official build))

我不确定在 AggregatingMergeTree 中通过“AND”逻辑合并的行中获取位图是否正确。

【问题讨论】:

【参考方案1】:

groupBitmapAnd 接受表示为 AggregateFunction(groupBitmap, UInt_) 类型的位图作为参数。

ClickHouse 不支持嵌套聚合类型(在本例中为 AggregateFunction(groupBitmapAnd, AggregateFunction(groupBitmap, UInt_)))。

所以它需要遵循官方文档中描述的模式 - https://clickhouse.tech/docs/en/sql-reference/aggregate-functions/reference/groupbitmapand/#groupbitmapand:

CREATE TABLE bitmap_column_expr_test2
(
    tag_id String,
    z AggregateFunction(groupBitmap, UInt32)
)
ENGINE = MergeTree
ORDER BY tag_id;

INSERT INTO bitmap_column_expr_test2 VALUES ('tag1', bitmapBuild(cast([1,2,3,4,5,6,7,8,9,10] as Array(UInt32))));
INSERT INTO bitmap_column_expr_test2 VALUES ('tag2', bitmapBuild(cast([6,7,8,9,10,11,12,13,14,15] as Array(UInt32))));
INSERT INTO bitmap_column_expr_test2 VALUES ('tag3', bitmapBuild(cast([2,4,6,8,10,12] as Array(UInt32))));

SELECT groupBitmapAnd(z) FROM bitmap_column_expr_test2 WHERE like(tag_id, 'tag%');
┌─groupBitmapAnd(z)─┐
│               3   │
└───────────────────┘

【讨论】:

谢谢,这是否意味着 clickhouse 中的 AggregatingMergeTree 不能支持使用 groupBitmapAndState(Merge) 聚合新的批处理位图和现有状态?我仍然很困惑为什么这不会发生,因为我可以使用 groupBitmapAndState 手动合并位图。 你能展示你如何手动合并 groupBitmapAndState 吗? 我想我可以像这样查询:SELECT groupBitmapAndState(z) FROM ( SELECT groupBitmapAndState(bitmapBuild(cast([1, 2, 3] as Array(UInt64)))) as z UNION ALL SELECT groupBitmapAndState(bitmapBuild(cast([1, 3] as Array(UInt64)))) as z ); 考虑更简单的例子 - SELECT groupBitmapAndState(bitmapBuild(CAST([1, 2, 3], 'Array(UInt64)'))) AS aa, groupBitmapAndMerge(aa)。结果你得到 DB::Exception: Aggregate function groupBitmapAndState(bitmapBuild(CAST([1, 2, 3], 'Array(UInt64)'))) is found inside another aggregate function in query: While processing groupBitmapAndState( bitmapBuild(CAST([1, 2, 3], 'Array(UInt64)'))) AS aa.. 我认为您提供的示例与我的情况有些不同。我想将 groupBitmapAndState 存储在表中,然后状态(位图)可以在我的查询期间合并或由 AggregatingMergeTree 自动合并。所以我认为不应该有任何嵌套的聚合函数,示例可能更像:SELECT groupBitmapAndState(aa) FROM ( SELECT groupBitmapAndState(bitmapBuild(CAST([1, 2, 3], 'Array(UInt64)'))) AS aa );

以上是关于如何在 clickhouse 中使用 groupBitmapAnd 和 AggregatingMergeTree 引擎?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ClickHouse 中使用分隔符连接 INT

如何使用golang在clickhouse中使用一个命令插入csv文件

如何在 Clickhouse 中使用 group by 间隔 1 小时?

如何在 Clickhouse 中使用主键和外键的功能?

如何在 ClickHouse 中使用 lambda max(a,b) 函数?

如何在 Windows 中使用 Clickhouse 访问 Docker Container 以加载数据? [复制]