如何处理 Clickhouse 的 AggregatingMergeTree 物化视图中的嵌套字段?
Posted
技术标签:
【中文标题】如何处理 Clickhouse 的 AggregatingMergeTree 物化视图中的嵌套字段?【英文标题】:How to handle nested fields in Clickhouse's AggregatingMergeTree Materialized View? 【发布时间】:2020-07-16 16:38:02 【问题描述】:有没有办法在 AggregatedMergeTree
物化视图中的 Clickhouse 中组合(连接)组中的 Nested
字段?
想象一下,我有一个表,其架构(简化)如下:
CREATE TABLE test
(
key1 String,
key2 String,
clicks Int32,
points Nested(x Int32, y Int32)
) Engine = Log
我希望能够使用AggregatingMergeTree
生成一个物化视图,通过“连接”它们来组合嵌套字段(好像嵌套记录可以像某些 SQL 方言那样连接为复杂值)。
如果我将其作为查询进行,则有可能:
SELECT
key1,
key2,
arrayMap(p -> p.1, points) as x,
arrayMap(p -> p.2, points) as y
FROM
(
SELECT
key1,
key2,
groupArray(tuple(x, y)) as points
FROM
(
SELECT
key1, key2, points.x as x, points.y as y
FROM test
ARRAY JOIN points
)
GROUP BY key1, key2
)
有没有办法在基于AggregatingMergeTree
引擎的物化视图中使用的查询中表达这一点?我能想到的最好的方法是这样的:
CREATE MATERIALIZED VIEW testagg1
engine = AggregatingMergeTree partition by key1 order by (key1, key2)
AS
SELECT
key1,
key2,
sumState(clicks) as clicks,
groupArrayState(points.x) as `points.x`,
groupArrayState(points.y) as `points.y`
FROM test
GROUP BY key1, key2
然后我可以使用这个查询得到扁平化的表单:
SELECT
arrayMap(p -> p.1, arrayZip(x, y)) as x1,
arrayMap(p -> p.2, arrayZip(x, y)) as y1
FROM
(
SELECT
key1,
key2,
groupArrayMerge(`points.x`) as x,
groupArrayMerge(`points.y`) as y
FROM testagg1
GROUP BY key1, key2
) as points
ARRAY JOIN x, y
它有效,但似乎有点复杂。
有没有更简单、更好的方法来做到这一点? 上面使用的groupArrayState
和groupArrayMerge
聚合是否保证以保持并行数组中 x/y 字段的相同顺序?
【问题讨论】:
【参考方案1】:Nested(x Int32, y Int32) -- 是 create table
命令减少数组样板的语法糖。
desc test
┌─name─────┬─type─────────┬
│ key1 │ String │
│ key2 │ String │
│ clicks │ Int32 │
│ points.x │ Array(Int32) │
│ points.y │ Array(Int32) │
└──────────┴──────────────┴
我能想到的最好的方法是这样的: groupArrayState(points.x) 作为
points.x
, groupArrayState(points.y) aspoints.y
这是唯一的方法。这是官方/正确的 CH 方式。
上面使用的聚合保证保持相同 并行数组中 x/y 字段的排序?
是的,这是有保证的。
选择 arrayMap(p -> p.1, arrayZip(x, y)) 作为 x1, arrayMap(p -> p.2, arrayZip(x, y)) as y1
和这个一样
选择 x,y
不是吗?
【讨论】:
感谢丹尼斯的快速回复。是的,这个:sql SELECT arrayMap(p -> p.1, arrayZip(x, y)) as x1, arrayMap(p -> p.2, arrayZip(x, y)) as y1
并且您不需要数组映射来提取元组元素。试试select [(1,2),(3,4)] a, a.1, a.2
以上是关于如何处理 Clickhouse 的 AggregatingMergeTree 物化视图中的嵌套字段?的主要内容,如果未能解决你的问题,请参考以下文章
clickhouse实践关于clickhouse对空值的处理总结