如何通过 AppSync 从 DynamoDB 向 return 指定属性

How to specify attributes to return from DynamoDB through AppSync

我有一个 AppSync 管道解析器。第一个函数在 ElasticSearch 数据库中查询 DynamoDB 键。第二个函数使用提供的键查询 DynamoDB。这一切都很好,直到我 运行 进入 1 MB limit of AppSync。由于大部分数据都在我不需要的几个 attributes/columns 中,我想将结果限制为我需要的属性。

我尝试添加 AttributesToGet 和 ProjectionExpression (from here),但都给出了如下错误:

{
  "data": {
    "getItems": null
  },
  "errors": [
    {
      "path": [
        "getItems"
      ],
      "data": null,
      "errorType": "MappingTemplate",
      "errorInfo": null,
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "Unsupported element '$[tables][dev-table-name][projectionExpression]'."
    }
  ]
}

我的 DynamoDB 函数请求映射模板看起来像(returns 结果只要数据小于 1 MB):

#set($ids = [])
#foreach($pResult in ${ctx.prev.result})
    #set($map = {})
    $util.qr($map.put("id", $util.dynamodb.toString($pResult.id)))
    $util.qr($map.put("ouId", $util.dynamodb.toString($pResult.ouId)))
    $util.qr($ids.add($map))
#end
{
    "version" : "2018-05-29",
    "operation" : "BatchGetItem",
    "tables" : {
        "dev-table-name": {
            "keys": $util.toJson($ids),
            "consistentRead": false
        }
    }
}

AppSync 不支持投影,但您可以在响应模板中明确定义要 return 的字段,而不是 return 整个结果集。

{
  "id": "$ctx.result.get('id')",
  "name": "$ctx.result.get('name')",
   ...
}

我联系了 AWS 人员,他们确认目前不支持 ProjectionExpression,他们需要一段时间才能使用它。

相反,我创建了一个 lambda 来从 DynamoDB 中提取数据。

为了限制 DynamoDB 的结果,我在 AppSync 中使用 $ctx.info.selectionSetList 来获取请求列的列表,然后使用该列表指定要从 DynamoDB 中提取的数据。我需要获得多个结果,维护顺序,所以我使用 BatchGetItem,然后使用 LINQ 将结果与原始 ID 列表合并(这将 DynamoDB 结果恢复为正确的顺序,因为 C# 中的 BatchGetItem 不像 AppSync 那样保留排序顺序版本)。

因为我使用 C# 和许多库,冷启动时间有点长,所以我使用 Lambda Layers pre-JITed to Linux 这使我们能够将冷启动时间从~1.8 秒到~1 秒(当为 Lambda 使用 1024 GB RAM 时)。