如何在 aws 放大中使用 graphQL 限制

ali*_*hur 3 javascript amazon-dynamodb graphql aws-amplify

我是使用 aws-amplify 的新手,并且有一个与此类似的函数,它会调用一个查询listItems并返回isEnbledtrue(来自 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
 }
Run Code Online (Sandbox Code Playgroud)

Ben*_*Ben 11

DynamoDB 扫描与查询

您应该考虑将 GSI 添加到表中的“已启用”项目,然后进行查询,而不是扫描每个项目然后进行过滤。这将在查询时更有效(即更快和更便宜),但代价是写入和存储成本略高。通常这是一个很好的权衡。

分页

不管您是查询还是扫描,一旦结果集的大小变得太大(最大 1MB),您将不得不处理 DynamoDB 分页。如果结果集达到阈值,那么您将获得第一页结果和LastEvaluatedKey. 然后您需要再次查询,将LastEvaluatedKey值作为ExclusiveStartKey. 你一直这样做,直到你没有LastEvaluatedKey回来。

如果您更新您的 AppSync 架构和解析器以将其LastEvaluatedKey作为 a 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 架构和应用程序是最强大的解决方案。