问题
I am trying to build an AWS AppSync query with a list using 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))
}
However, trying it out with parameters like:
query ListItemsWithIdList {
listItemsWithIdList(first:20, ids: ["id1", "id2"]) {
items {
id
}
nextToken
}
}
It throws an error:
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]'"
It seems OK to use IN
for query comparison operator; however, how can I pass a String List
as a parameter and fetch the results whose IDs are among those parameters supplied?
EDIT: Corrected variable name typo.
回答1:
I don't think AWS AppSync support IN
just for now. I try to test your scenario and come up with a solution using contains()
function.
Here is the result after query:
Another alternative solution is to use Scan
(not recommended)
{
"version" : "2017-02-28",
"operation" : "Scan",
"filter" : {
"expression": "contains (:authors, author)",
"expressionValues" : {
":authors" : $util.dynamodb.toDynamoDBJson($ctx.args.authors)
}
}
}
Btw, AWS AppSync support BatchGetItem
operation. You can pass a list of keys in a single query and return the results from a table.
Reference: https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-dynamodb-batch.html
Here is an example and I tested it worked like charm:
## 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)
回答2:
I think there could be 2 issues here:
Your arguments in the
listItemsWithIdList
query accepts an argument nameduserIds
. You have$ctx.args.ids)
in your Resolver template. You need use the same argument name in both places.When you use
$util.dynamodb.toStringSet
in your Mapping Template, like you see in the error, it gets transformed to{ \":ids\" : {SS=[id1, id2]} }
. However, you want the id values to be contained within quotes. AWS AppSync provides another utility method for this purpose. You can change your template to use$util.dynamodb.toStringSetJson
, which then gets converted to{ \":ids\" : {SS=[\"id1\", \"id2\"]} }
.
Let me know if this resolved your issue. Here is the reference to the Resolver Mapping Template Utilities.
回答3:
Hopefully you have already resolved it. However, there are two issues in your setup:
This has to be a filter expression and since you don't have a key condition, this may even have to be a scan instead of a query
Then there are syntax issues (which is what the error is really because of): In the EXPRESSION, add parentheses to the variable "expression": "id IN (:ids"),
And in EXPRESSION VALUES use toStringSetJson instead of toStringSet "expressionValues" : { ":ids" : $util.dynamodb.toStringSetJson($ctx.args.ids) }
Hope this helps.
来源:https://stackoverflow.com/questions/52487030/querying-dynamodb-with-a-list-in-aws-appsync