使用 AWS AppSync 中的列表查询 DynamoDB
Querying DynamoDB with a list in AWS AppSync
我正在尝试使用 IN
:
使用列表构建 AWS AppSync 查询
{
"version" : "2017-02-28",
"operation" : "Query",
"index" : "my-index",
"query" : {
"expression": "id IN :ids",
"expressionValues" : { ":ids" : $util.dynamodb.toStringSet($ctx.args.ids) }
},
"limit": $util.defaultIfNull(${ctx.args.first}, 20),
"nextToken": $util.toJson($util.defaultIfNullOrBlank($ctx.args.after, null))
}
但是,使用如下参数进行尝试:
query ListItemsWithIdList {
listItemsWithIdList(first:20, ids: ["id1", "id2"]) {
items {
id
}
nextToken
}
}
它抛出一个错误:
Unable to parse the JSON document: 'Unexpected character ('S' (code 83)): was expecting double-quote to start field name
at [Source: (String)\"{
\"version\" : \"2017-02-28\",
\"operation\" : \"Query\",
\"index\" : \"my-index\",
\"query\" : {
\"expression\": \"id IN :ids\",
\"expressionValues\" : { \":ids\" : {SS=[id1, id2]} }
},
\"limit\": 20,
\"nextToken\": null
}\"; line: 7, column: 47]'"
查询比较运算符使用IN
似乎没问题;但是,如何将 String List
作为参数传递并获取其 ID 在提供的参数中的结果?
编辑:更正了变量名称拼写错误。
我认为这里可能有两个问题:
您在 listItemsWithIdList
查询中的参数接受名为 userIds
的参数。您的解析器模板中有 $ctx.args.ids)
。您需要在两个地方使用相同的参数名称。
当您在映射模板中使用 $util.dynamodb.toStringSet
时,就像您在错误中看到的那样,它会转换为 { \":ids\" : {SS=[id1, id2]} }
。但是,您希望将 id 值包含在引号内。 AWS AppSync 为此提供了另一种实用方法。您可以将模板更改为使用 $util.dynamodb.toStringSetJson
,然后它会转换为 { \":ids\" : {SS=[\"id1\", \"id2\"]} }
.
如果这解决了您的问题,请告诉我。这是对 Resolver Mapping Template Utilities.
的引用
我认为 AWS AppSync 暂时不支持 IN
。我尝试测试您的场景并使用 contains()
函数提出解决方案。
查询后结果如下:
另一种替代方案是使用Scan
(不推荐)
{
"version" : "2017-02-28",
"operation" : "Scan",
"filter" : {
"expression": "contains (:authors, author)",
"expressionValues" : {
":authors" : $util.dynamodb.toDynamoDBJson($ctx.args.authors)
}
}
}
顺便说一句,AWS AppSync 支持 BatchGetItem
操作。您可以在单个查询中传递键列表,并 return 来自 table 的结果。
参考:https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-dynamodb-batch.html
这是一个示例,我测试它像魅力一样有效:
## REQUEST MAPPING
#set($authors = [])
#foreach( $author in $ctx.args.authors )
#set($map = {})
$util.qr($map.put("author", $util.dynamodb.toString($author)))
$util.qr($authors.add($map))
#end
{
"version" : "2018-05-29",
"operation" : "BatchGetItem",
"tables" : {
"tbDiary": {
"keys": $util.toJson($authors),
"consistentRead": true
}
}
}
## RESPONSE MAPPING
$util.toJson($ctx.result.data.tbDiary)
希望你已经解决了。但是,您的设置中存在两个问题:
这必须是一个过滤表达式,并且由于您没有关键条件,这甚至可能必须是扫描而不是查询
然后是语法问题(这是错误的真正原因):
在 EXPRESSION 中,为变量添加括号
"expression": "id IN (:ids"),
并且在 EXPRESSION VALUES 中使用 toStringSetJson 而不是 toStringSet
"expressionValues" : { ":ids" : $util.dynamodb.toStringSetJson($ctx.args.ids) }
希望这对您有所帮助。
我正在尝试使用 IN
:
{
"version" : "2017-02-28",
"operation" : "Query",
"index" : "my-index",
"query" : {
"expression": "id IN :ids",
"expressionValues" : { ":ids" : $util.dynamodb.toStringSet($ctx.args.ids) }
},
"limit": $util.defaultIfNull(${ctx.args.first}, 20),
"nextToken": $util.toJson($util.defaultIfNullOrBlank($ctx.args.after, null))
}
但是,使用如下参数进行尝试:
query ListItemsWithIdList {
listItemsWithIdList(first:20, ids: ["id1", "id2"]) {
items {
id
}
nextToken
}
}
它抛出一个错误:
Unable to parse the JSON document: 'Unexpected character ('S' (code 83)): was expecting double-quote to start field name
at [Source: (String)\"{
\"version\" : \"2017-02-28\",
\"operation\" : \"Query\",
\"index\" : \"my-index\",
\"query\" : {
\"expression\": \"id IN :ids\",
\"expressionValues\" : { \":ids\" : {SS=[id1, id2]} }
},
\"limit\": 20,
\"nextToken\": null
}\"; line: 7, column: 47]'"
查询比较运算符使用IN
似乎没问题;但是,如何将 String List
作为参数传递并获取其 ID 在提供的参数中的结果?
编辑:更正了变量名称拼写错误。
我认为这里可能有两个问题:
您在
listItemsWithIdList
查询中的参数接受名为userIds
的参数。您的解析器模板中有$ctx.args.ids)
。您需要在两个地方使用相同的参数名称。当您在映射模板中使用
$util.dynamodb.toStringSet
时,就像您在错误中看到的那样,它会转换为{ \":ids\" : {SS=[id1, id2]} }
。但是,您希望将 id 值包含在引号内。 AWS AppSync 为此提供了另一种实用方法。您可以将模板更改为使用$util.dynamodb.toStringSetJson
,然后它会转换为{ \":ids\" : {SS=[\"id1\", \"id2\"]} }
.
如果这解决了您的问题,请告诉我。这是对 Resolver Mapping Template Utilities.
的引用我认为 AWS AppSync 暂时不支持 IN
。我尝试测试您的场景并使用 contains()
函数提出解决方案。
查询后结果如下:
另一种替代方案是使用Scan
(不推荐)
{
"version" : "2017-02-28",
"operation" : "Scan",
"filter" : {
"expression": "contains (:authors, author)",
"expressionValues" : {
":authors" : $util.dynamodb.toDynamoDBJson($ctx.args.authors)
}
}
}
顺便说一句,AWS AppSync 支持 BatchGetItem
操作。您可以在单个查询中传递键列表,并 return 来自 table 的结果。
参考:https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-dynamodb-batch.html
这是一个示例,我测试它像魅力一样有效:
## REQUEST MAPPING
#set($authors = [])
#foreach( $author in $ctx.args.authors )
#set($map = {})
$util.qr($map.put("author", $util.dynamodb.toString($author)))
$util.qr($authors.add($map))
#end
{
"version" : "2018-05-29",
"operation" : "BatchGetItem",
"tables" : {
"tbDiary": {
"keys": $util.toJson($authors),
"consistentRead": true
}
}
}
## RESPONSE MAPPING
$util.toJson($ctx.result.data.tbDiary)
希望你已经解决了。但是,您的设置中存在两个问题:
这必须是一个过滤表达式,并且由于您没有关键条件,这甚至可能必须是扫描而不是查询
然后是语法问题(这是错误的真正原因): 在 EXPRESSION 中,为变量添加括号 "expression": "id IN (:ids"),
并且在 EXPRESSION VALUES 中使用 toStringSetJson 而不是 toStringSet "expressionValues" : { ":ids" : $util.dynamodb.toStringSetJson($ctx.args.ids) }
希望这对您有所帮助。