如何通过 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 时)。
我有一个 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 时)。