如何在 aws amplify 中使用 graphQL 限制
How to use graphQL limit in aws amplify
我是使用 aws-amplify 的新手,并且有一个类似于此的函数,它命中一个名为 listItems
和 returns 项的查询,其中 isEnbled
为真(来自 DynamoDB) .
我希望它能过滤整个 table,这可能很大。因此,我无法简单地设置一个像 1000 这样的限制并保持不变。有没有办法指定无限查询并扫描table中的所有内容?还是我应该使用不同的 属性?
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
}
DynamoDB 扫描与查询
与其扫描每个项目然后过滤,您应该考虑将 GSI 添加到 table 中的 "enabled" 项目然后查询它。这将在查询时更有效率(即更快和更便宜),但写入和存储成本略高。通常这是一个很好的权衡。
分页
无论您是查询还是扫描,一旦结果集的大小变得太大(最大 1MB),您将不得不处理 DynamoDB 分页。如果结果集达到阈值,那么您将获得第一页结果和 LastEvaluatedKey
。然后您需要再次查询,将 LastEvaluatedKey
值作为 ExclusiveStartKey
传递。你一直这样做,直到没有 LastEvaluatedKey
回来。
如果您更新您的 AppSync 架构和解析器以将此 LastEvaluatedKey
作为 paginationToken
(或您想要调用的任何名称)传回,那么您可以通过传递最新的令牌以获取下一页结果。如果您不需要一次获得所有结果,您可以考虑懒惰地调用这些结果,以便只在需要时请求另一个页面或结果。
其他注意事项
还有一些其他方法。
如果您知道过滤后的结果集将始终小于 1MB,一种方法是将您的 DynamoDB 数据源换成 Lambda,并在您的 lambda 内循环逐步扫描和过滤(或查询)DynamoDB 页面在 return 将过滤后的结果传输到您的 AppSync 解析器之前,然后从那里 return 传输到您的应用程序。
问题包括:
- 如何保证过滤后的结果集始终小于 1MB(AppSync 的限制)
- 如何保证lambda会return及时(AppSync时间限制)
- 您正在扫描整个 table(如果您扫描而不是查询)但您只对这些项目的子集("isEnabled" 项目)感兴趣
或者,如果您可以将您的项目(或您的 "isEnabled" 项目)分成多个组,您可以扇出您的扫描(或查询)以在像以前一样累积结果之前实施并行扫描(或查询)。这可能会启用更快的扫描,但您仍然会在时间和负载大小方面受到限制,因此对于大型 table 扫描来说仍然存在问题。
总结
- DynamoDB 强制对结果进行分页(最大 1MB)
- AppSync 限制负载大小(最大 1MB,如果您也打算使用订阅则更少)
- DynamoDB 扫描的效率低于查询。考虑添加 GSI,以便您可以查询而不是扫描/过滤。
- 在 Lambda 或 AppSync VTL 中累积结果页面的黑客攻击很脆弱,可能不适用于巨大的 tables
- 在您的应用程序中实施分页将需要更新您的 AppSync 架构以传入和传出 DynamoDB "pagination tokens" (
LastEvaluatedKey
/ ExclusiveStartKey
)。
添加 GSI,查询它(而不是扫描),然后将分页添加到您的 AppSync 架构和应用程序是最可靠的解决方案。
我是使用 aws-amplify 的新手,并且有一个类似于此的函数,它命中一个名为 listItems
和 returns 项的查询,其中 isEnbled
为真(来自 DynamoDB) .
我希望它能过滤整个 table,这可能很大。因此,我无法简单地设置一个像 1000 这样的限制并保持不变。有没有办法指定无限查询并扫描table中的所有内容?还是我应该使用不同的 属性?
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
}
DynamoDB 扫描与查询
与其扫描每个项目然后过滤,您应该考虑将 GSI 添加到 table 中的 "enabled" 项目然后查询它。这将在查询时更有效率(即更快和更便宜),但写入和存储成本略高。通常这是一个很好的权衡。
分页
无论您是查询还是扫描,一旦结果集的大小变得太大(最大 1MB),您将不得不处理 DynamoDB 分页。如果结果集达到阈值,那么您将获得第一页结果和 LastEvaluatedKey
。然后您需要再次查询,将 LastEvaluatedKey
值作为 ExclusiveStartKey
传递。你一直这样做,直到没有 LastEvaluatedKey
回来。
如果您更新您的 AppSync 架构和解析器以将此 LastEvaluatedKey
作为 paginationToken
(或您想要调用的任何名称)传回,那么您可以通过传递最新的令牌以获取下一页结果。如果您不需要一次获得所有结果,您可以考虑懒惰地调用这些结果,以便只在需要时请求另一个页面或结果。
其他注意事项
还有一些其他方法。
如果您知道过滤后的结果集将始终小于 1MB,一种方法是将您的 DynamoDB 数据源换成 Lambda,并在您的 lambda 内循环逐步扫描和过滤(或查询)DynamoDB 页面在 return 将过滤后的结果传输到您的 AppSync 解析器之前,然后从那里 return 传输到您的应用程序。
问题包括:
- 如何保证过滤后的结果集始终小于 1MB(AppSync 的限制)
- 如何保证lambda会return及时(AppSync时间限制)
- 您正在扫描整个 table(如果您扫描而不是查询)但您只对这些项目的子集("isEnabled" 项目)感兴趣
或者,如果您可以将您的项目(或您的 "isEnabled" 项目)分成多个组,您可以扇出您的扫描(或查询)以在像以前一样累积结果之前实施并行扫描(或查询)。这可能会启用更快的扫描,但您仍然会在时间和负载大小方面受到限制,因此对于大型 table 扫描来说仍然存在问题。
总结
- DynamoDB 强制对结果进行分页(最大 1MB)
- AppSync 限制负载大小(最大 1MB,如果您也打算使用订阅则更少)
- DynamoDB 扫描的效率低于查询。考虑添加 GSI,以便您可以查询而不是扫描/过滤。
- 在 Lambda 或 AppSync VTL 中累积结果页面的黑客攻击很脆弱,可能不适用于巨大的 tables
- 在您的应用程序中实施分页将需要更新您的 AppSync 架构以传入和传出 DynamoDB "pagination tokens" (
LastEvaluatedKey
/ExclusiveStartKey
)。
添加 GSI,查询它(而不是扫描),然后将分页添加到您的 AppSync 架构和应用程序是最可靠的解决方案。