如何在 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 引擎?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用golang在clickhouse中使用一个命令插入csv文件
如何在 Clickhouse 中使用 group by 间隔 1 小时?