使用AWS AppSync中的列表查询DynamoDB

时间:2018-09-24 20:40:33

标签: amazon-web-services amazon-dynamodb 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在提供的那些参数之中的结果?

编辑:更正了变量名的错字。

3 个答案:

答案 0 :(得分:2)

我不认为AWS AppSync仅暂时支持IN。我尝试测试您的情况并使用contains()函数提出解决方案。

enter image description here

以下是查询后的结果:

enter image description here

另一种替代解决方案是使用Scan(不推荐)

{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "filter" : {
        "expression": "contains (:authors, author)",
        "expressionValues" : {
            ":authors" : $util.dynamodb.toDynamoDBJson($ctx.args.authors)
        }
    }
}

顺便说一句,AWS AppSync支持BatchGetItem操作。您可以在单个查询中传递键列表,然后从表中返回结果。
参考: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)

答案 1 :(得分:0)

我认为这里可能有2个问题:

  • 您在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.

的引用

答案 2 :(得分:0)

希望您已经解决了它。但是,您的设置中存在两个问题:

这必须是过滤器表达式,并且由于您没有关键条件,所以甚至可能必须是扫描而不是查询

然后是语法问题(这是错误的真正原因): 在EXPRESSION中,在变量中添加括号 “ expression”:“ id IN(:ids”),

并且在EXPRESSION VALUES中使用toStringSetJson而不是toStringSet “ expressionValues”:{“:ids”:$ util.dynamodb.toStringSetJson($ ctx.args.ids)}

希望这会有所帮助。