如何在单个GraphQL查询中实现多聚合统计(基于Hasura)
在Hasura GraphQL中实现多条件聚合(替代PostgreSQL的FILTER语法)
要在单个Hasura GraphQL查询中实现你需要的多值聚合,有两种实用方案:
方案一:创建自定义SQL函数并暴露给GraphQL
Hasura默认的聚合查询不支持PostgreSQL的FILTER语法,所以可以先写一个SQL函数封装统计逻辑,再让Hasura将其作为查询字段暴露:
- 执行以下SQL创建函数:
CREATE OR REPLACE FUNCTION ad_interaction_stats(ad_id_param UUID, start_date TIMESTAMP) RETURNS TABLE(clicked INT, shown INT, dismissed INT) AS $$ SELECT count(*) FILTER (WHERE interaction_type = 'clicked') AS clicked, count(*) FILTER (WHERE interaction_type = 'shown') AS shown, count(*) FILTER (WHERE interaction_type = 'dismissed') AS dismissed FROM ads.interaction WHERE ad_id = ad_id_param AND created_at >= start_date GROUP BY ad_id; $$ LANGUAGE sql STABLE;
在Hasura控制台中,进入
数据->函数,找到这个函数,开启追踪,并确认参数和返回类型配置正确。之后就能直接在GraphQL中查询:
query AdStatistics { ad_interaction_stats( ad_id_param: "7e9250bc-4f85-45ad-900d-f08558ebc775", start_date: "2023-06-22T00:00:00Z" ) { clicked shown dismissed } }
方案二:利用Hasura的group_by功能(无需自定义函数)
如果不想创建额外函数,可以通过分组查询获取各类型的统计,再在前端或通过计算字段整理结果:
基础分组查询
直接按ad_id和interaction_type分组,获取每个类型的计数:
query AdStatistics { ads_interaction_group_by( where: { created_at: {_gte: "2023-06-22"}, ad_id: {_eq: "7e9250bc-4f85-45ad-900d-f08558ebc775"}, interaction_type: {_in: ["clicked", "shown", "dismissed"]} }, group_by: [ad_id, interaction_type] ) { ad_id interaction_type aggregate { count } } }
返回结果会是每个交互类型对应的统计项,前端可以将其映射为扁平的统计对象。
结合计算字段实现后端整理
如果希望后端直接返回扁平结构,可以给ads.interaction表添加计算字段:
- 在Hasura控制台进入
数据->表->ads.interaction->计算字段 - 添加计算字段,名称设为
interaction_stats,SQL定义为:
SELECT json_object_agg(interaction_type, count) FROM ( SELECT interaction_type, count(*) as count FROM ads.interaction WHERE ad_id = current_table.ad_id AND created_at >= '2023-06-22' GROUP BY interaction_type ) as stats
之后查询时就能直接拿到包含所有统计的JSON对象:
query AdStatistics { ads_interaction( where: { ad_id: {_eq: "7e9250bc-4f85-45ad-900d-f08558ebc775"}, created_at: {_gte: "2023-06-22"} } ) { interaction_stats } }
方案对比
- 自定义函数:返回结构完全匹配需求,查询逻辑简洁,但需要维护额外的SQL函数。
- group_by方案:无需额外创建函数,但需要前端或计算字段处理结果结构。
内容的提问来源于stack exchange,提问作者Wiezalditzijn
相关产品推荐
相关产品推荐

