多个聚合查询合并为一个GraphQL查询。

huangapple go评论60阅读模式
英文:

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

  1. 定义一个新的type
type ViewStats {
  clicked: Number
  shown: Number
  dismissed: Number
}
  1. 在父对象中使用此字段,例如:
type Advertisement {
  id: ID!
  其他字段
  stats: ViewStats
}
  1. 在您的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

该查询将返回clickedshowndismissed,这将填充ViewStats类型的三个字段。

英文:
  1. Define a new type:
type ViewStats {
  clicked: Number
  shown: Number
  dismissed: Number
}
  1. Use this field in the parent object, ex:
type Advertisement {
  id: ID!
  …other fields
  stats: ViewStats
}
  1. In the field resolver for the stats field under your Advertisement 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.

huangapple
  • 本文由 发表于 2023年7月7日 03:05:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76631853.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定