GraphQL中如何使用Group By?查询过滤器内能否用日期函数?
解决AWS Amplify @searchable按年份聚合比赛数据的问题
核心问题说明
你想要的GetYear(playedOn)这种直接在聚合字段中提取年份的写法,目前AWS Amplify的@searchable指令生成的GraphQL查询并不支持。不过可以通过两种方案实现按年份分组,同时聚合比赛总数和setsWon总和:
方案1:添加派生年份字段(推荐,查询更直观)
直接在数据模型中新增一个存储年份的字段,写入数据时自动从playedOn中提取年份,后续聚合直接基于这个字段操作。
修改数据模型
type Match @model @searchable { id: ID! playedOn: AWSDate! year: Int! # 新增字段,存储比赛年份 playerId: ID! setsWon: Int! # 其他字段... }
实现年份自动填充
- 前端写入数据时,从
playedOn字符串中截取前4位转为整数赋值给year(比如用new Date(playedOn).getFullYear()) - 或者用AWS Lambda触发器(DynamoDB Stream),在数据写入/更新时自动计算并填充
year字段
最终查询
这个查询会按年份分组,同时返回每组的比赛总数(doc_count)和setsWon总和:
query MyQuery { searchMatches( filter: {playerId: {eq: "1"}}, aggregates: [ { field: year, name: "year_groups", type: terms, aggregates: [ { field: setsWon, name: "total_sets_won", type: sum } ] } ] ) { aggregateItems { result { ... on SearchableAggregateBucketResult { buckets { key # 年份数字(如2023) doc_count # 该年份的比赛总数 aggregateItems { result { ... on SearchableAggregateSumResult { value # 该年份的setsWon总和 } } name } } } } name } total } }
方案2:使用date_histogram聚合(无需修改模型)
利用Elasticsearch的date_histogram聚合类型,直接对playedOn字段按年分桶,无需新增字段。
查询示例
query MyQuery { searchMatches( filter: {playerId: {eq: "1"}}, aggregates: [ { field: playedOn, name: "year_groups", type: date_histogram, config: { interval: "year" # 指定按年分桶 }, aggregates: [ { field: setsWon, name: "total_sets_won", type: sum } ] } ] ) { aggregateItems { result { ... on SearchableAggregateDateHistogramResult { buckets { key_as_string # 格式为"2023-01-01T00:00:00.000Z",取前4位就是年份 doc_count # 该年份的比赛总数 aggregateItems { result { ... on SearchableAggregateSumResult { value # 该年份的setsWon总和 } } name } } } } name } total } }
注意点
返回的key_as_string是ISO格式的日期,需要在客户端截取前4位获取年份;key是时间戳,也可以转换为年份使用。
内容的提问来源于stack exchange,提问作者The Jonas Persson
相关产品推荐
相关产品推荐

