如何在AWS AppSync中拆分订阅的OR过滤(解决IN操作符限制)
问题描述
我正在开发一款基于AWS AppSync的消息应用,定义了如下Message类型:
type Message @model @auth( rules: [ { allow: groups, groups: ["externalUser"], operations: [] } ] ) { id: ID! channelId: ID! senderId: ID! channel: Channel @connection(fields: ["channelId"]) createdAt: AWSDateTime! text: String }
我创建了onCreateMessage订阅,需要过滤出用户所在频道的消息。从权限表获取用户的频道列表后,在响应映射模板中添加了如下代码:
$extensions.setSubscriptionFilter({ "filterGroup": [ { "filters" : [ { "fieldName" : "channelId", "operator" : "in", "value" : $context.result.channelIds } ] } ] }) $util.toJson($messageResult)
这段代码在用户频道数≤5时正常工作,但频道数超过5时会报错:
{ "message": "Connection failed: {"errors":[{"message":"subscription exceeds maximum value limit 5 for operator `in`.","errorCode":400}]}" }
作为VTL新手,请问如何将该过滤拆分为多个OR逻辑的条件?
解决方案
AWS AppSync的in操作符最多支持5个值,要处理超过5个频道ID的情况,需要将频道列表拆分为每组最多5个ID,然后把每组作为独立的filterGroup——AppSync中不同filterGroup之间是OR逻辑,同一个filterGroup内的filters是AND逻辑。
用VTL实现的代码如下:
#set($channelIds = $context.result.channelIds) #set($filterGroups = []) #foreach($i in [0, 5, 10, 15, 20]) # 可根据实际最大频道数调整步长上限 #if($i < $channelIds.size()) #set($endIndex = $math.add($i, 5)) #if($endIndex > $channelIds.size()) #set($endIndex = $channelIds.size()) #end #set($chunk = $channelIds.subList($i, $endIndex)) #set($filter = { "filters": [ { "fieldName": "channelId", "operator": "in", "value": $chunk } ] }) #set($discard = $filterGroups.add($filter)) #end #end $extensions.setSubscriptionFilter({ "filterGroup": $filterGroups }) $util.toJson($messageResult)
代码说明
- 先获取用户的频道ID列表,初始化空的
filterGroups数组 - 按步长5遍历数组索引,拆分出最多5个元素的子数组
- 每个子数组对应一个
filterGroup,内部仅包含一个in操作的过滤规则 - 最后将所有生成的filterGroups传入
setSubscriptionFilter
比如用户有6个频道ID时,会生成两个filterGroup:第一个包含前5个ID,第二个包含第6个ID,两者通过OR逻辑组合,既实现了全频道消息过滤,又避开了in操作符的5值限制。
内容的提问来源于stack exchange,提问作者user16531209
相关产品推荐
相关产品推荐

