英文:
Multiple aggregations into one graphql query
问题
我正在尝试在一个GraphQL查询中汇总多个值。似乎无法做到这一点(使用Hasura GraphiQL构建查询)。在Postgres中可以做类似的事情。
背景
我想展示关于我的广告展示次数、点击次数和关闭次数的统计信息。在GraphQL中,我需要分别查询 interaction_type
为 "shown"
、"dismissed"
或 "clicked"
的数据。
我的目标是在GraphQL中重新创建此SQL查询。
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 group by ad_id
英文:
I am trying to aggregate multiple values in one graphQL query. It seems to be impossible to do this (Using Hasura GraphiQL to build the query). It is possible to do something like it in Postgres.
Background
I want to show statistics about my advertisement's number of views (shown), clicks and dismisses. In graphQL I need to make separate queries for interaction_type=
"shown"
, "dismissed"
or "clicked"
query AdStatistics {
ads_interaction_aggregate(
where: {created_at: {_gte: "2023-06-22"},
interaction_type: {_eq: "shown"},
ad_id: {_eq: "7e9250bc-4f85-45ad-900d-f08558ebc775"}}) {
aggregate {
count(columns: [interaction_type], distinct: false)
}
}
}
My goal is to re-create this SQL query in GraphQL.
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 group by ad_id
答案1
得分: 1
披露:我是Hasura的开发人员。
目前,Hasura不直接支持您想要的功能。但是,我们目前正在考虑在将来添加group_by
支持到聚合操作,这将允许您按ad_id
,然后按interaction_type
进行分组,然后应用计数聚合。请参阅此 GitHub 问题,我们已发布了一个RFC。
目前,实现您想要的最简单的方法是使用本地查询功能。本地查询应该允许您使用所需的SQL代码片段从GraphQL中进行查询。
例如,您可以在本地查询中使用以下参数化SQL查询:
select
ad_id,
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 created_at >= {{created_since}}
group by ad_id
然后,一旦将其设置为名为ads_interaction_summary
的本地查询,您可以像这样从GraphQL中进行查询:
query {
ads_interaction_summary(
args: { created_since: "2023-06-22" }
where: { ad_id: {_eq: "7e9250bc-4f85-45ad-900d-f08558ebc775"} }
) {
clicked
shown
dismissed
}
}
英文:
Disclosure: I'm a developer at Hasura.
At the moment, Hasura doesn't directly support what you want. However, we're currently thinking about adding group_by
support to aggregations that in the future will allow you to group by ad_id
, then interaction_type
, then apply a count aggregation. Please see this GitHub issue where we've put out an RFC.
For now, the easiest way to achieve what you want is to use the Native Queries feature. Native queries should allow you to take your desired SQL snippet and query it from GraphQL.
For example, you could use this parameterised SQL query in your Native Query:
select
ad_id,
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 created_at >= {{created_since}}
group by ad_id
and then once that's set up as a Native Query named ads_interaction_summary
, you could query it from your GraphQL like so:
query {
ads_interaction_summary(
args: { created_since: "2023-06-22" }
where: { ad_id: {_eq: "7e9250bc-4f85-45ad-900d-f08558ebc775"} }
) {
clicked
shown
dismissed
}
}
答案2
得分: 0
- 定义一个新的
type
:
type ViewStats {
clicked: Number
shown: Number
dismissed: Number
}
- 在父对象中使用此字段,例如:
type Advertisement {
id: ID!
…其他字段
stats: ViewStats
}
- 在您的
Advertisement
对象下的stats
字段解析器中,使用您先前定义的查询:
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=${parent.id}
group by ad_id
该查询将返回clicked
、shown
和dismissed
,这将填充ViewStats
类型的三个字段。
英文:
- Define a new
type
:
type ViewStats {
clicked: Number
shown: Number
dismissed: Number
}
- Use this field in the parent object, ex:
type Advertisement {
id: ID!
…other fields
stats: ViewStats
}
- In the field resolver for the
stats
field under yourAdvertisement
object use your previously defined query:
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=${parent.id}
group by ad_id
That query will return clicked
, shown
and dismissed
which will populate the 3 fields of the ViewStats
type.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论