简体   繁体   中英

Querying DynamoDB with a list in AWS AppSync

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.

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)

I think there could be 2 issues here:

  • Your arguments in the listItemsWithIdList query accepts an argument named userIds . 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM