如何在 aws amplify 中使用 graphQL 限制
Posted
技术标签:
【中文标题】如何在 aws amplify 中使用 graphQL 限制【英文标题】:How to use graphQL limit in aws amplify 【发布时间】:2020-08-19 15:29:03 【问题描述】:我是使用 aws-amplify 的新手,并且有一个与此类似的函数,它会命中一个名为 listItems
的查询并返回 isEnbled
为 true 的项目(来自 DynamoDB)。
我希望这可以过滤整个可能很大的表。因此,我无法简单地设置 1000 之类的限制并保持不变。有没有办法指定无限查询并扫描表中的所有内容?还是我应该使用其他属性?
import API from 'aws-amplify'
export async function getAllEnabledListItems()
const data = await API.graphql(
query: queries.listItems,
variables: filter: isEnabled: eq: true , limit: 10000 ,
authMode: 'AMAZON_COGNITO_USER_POOLS'
)
return data
【问题讨论】:
【参考方案1】:DynamoDB 扫描与查询
您应该考虑将 GSI 添加到表中“已启用”的项目中,然后对其进行查询,而不是扫描每个项目然后进行过滤。这将在查询时更加高效(即更快、更便宜),但代价是写入和存储成本略高。通常这是一个很好的权衡。
分页
无论您是查询还是扫描,一旦结果集的大小变得太大(最大 1MB),您将不得不处理 DynamoDB 分页。如果结果集达到阈值,那么您将获得第一页结果和LastEvaluatedKey
。然后您需要再次查询,将LastEvaluatedKey
值作为ExclusiveStartKey
传递。你一直这样做,直到你没有收到LastEvaluatedKey
回复。
如果您更新 AppSync 架构和解析器以将此 LastEvaluatedKey
作为 paginationToken
(或您想调用的任何名称)传回,那么您可以从您的应用程序中重复重新查询并传递最新令牌以获取下一页结果。如果您不需要一次获得所有结果,您可能会考虑懒惰地调用这些结果,以便仅在需要时才请求另一个页面或结果。
其他注意事项
还有其他一些方法。
如果您知道过滤后的结果集将始终小于 1MB,则一种方法是将您的 DynamoDB 数据源换成 Lambda,然后在 lambda 内循环扫描和过滤(或查询)DynamoDB 页面,然后再返回过滤结果到您的 AppSync 解析器,然后从那里返回到您的应用程序。
问题包括:
如何保证过滤后的结果集始终小于 1MB(AppSync 的限制) 如何保证 lambda 及时返回(AppSync 时间限制) 您正在扫描整个表(如果您扫描而不是查询),但您只对这些项目的子集(“isEnabled”项目)感兴趣或者,如果您可以将您的项目(或“isEnabled”项目)分成多个组,您可以像以前一样在累积结果之前展开扫描(或查询)以实施并行扫描(或查询)。这可能会实现更快的扫描,但您仍然会受到时间和负载大小的限制,因此对于大型表扫描仍然存在问题。
总结
DynamoDB 强制对结果进行分页(最大 1MB) AppSync 限制负载大小(最大 1MB,如果您也打算使用订阅,则更小) DynamoDB 扫描的效率低于查询。考虑添加 GSI,以便您可以查询而不是扫描/过滤。 在 Lambda 或 AppSync VTL 中累积结果页面的技巧很脆弱,可能不适用于大型表 在您的应用中实现分页将需要更新您的 AppSync 架构以传入和传出 DynamoDB“分页令牌”(LastEvaluatedKey
/ExclusiveStartKey
)。
添加 GSI,对其进行查询(而不是扫描),然后将分页添加到您的 AppSync 架构和应用程序是最可靠的解决方案。
【讨论】:
感谢您的精彩解释,这很有效。我们在状态字段上使用了全局二级索引。它似乎不喜欢在布尔字段上使用 GSI。 有没有办法获取记录总数?在客户端呈现页码? 不像这篇文章建议的那样创建自己的paginationToken
,我看到映射模板现在有nextToken
,它会自动处理这个:docs.aws.amazon.com/appsync/latest/devguide/…以上是关于如何在 aws amplify 中使用 graphQL 限制的主要内容,如果未能解决你的问题,请参考以下文章
在 AWS Amplify GraphQL 中对结果进行排序而不进行过滤
如何在 aws amplify 中使用 graphQL 限制
如何在带有 Typescript 项目的 React Native 中使用 AWS Amplify?