背景
我们将 AWS AppSync 与附加的 DynamoDB 数据源一起使用。在将批处理结果返回给我们的客户之前尝试过滤查询时,我们遇到了一个非常令人困惑的情况。目标是根据被过滤的键中包含的子字符串过滤我们的结果。
我们的 DynamoDB 有一个复合键,如下所示:
nameGroup: String // partition key; the first letter of the sort key value
name: String // sort key; the full name of the object
Attributes:
locationID: String // a three-character string
officialName: String // a more formal name
... etc.
例如:
nameGroup: A
name: Australia
locationID: AUS
officialName: Australia
... etc.
在这里你会找到我们的请求解析器:
{
"version" : "2017-02-28",
"operation" : "Query",
"index" : "nameGroup-locationID-index",
"query" : {
## Query based off of first letter of supplied String **
"expression" : "nameGroup = :nameGroup",
"expressionValues" : {
":nameGroup" : $util.dynamodb.toDynamoDBJson(${ctx.args.filter.substring(0,1)})
}
},
"filter" : {
## Filter query list with 'contains' expression **
"expression" : "contains(#name, :name)",
"expressionNames" : {
"#name" : "name"
},
"expressionValues" : {
":name" : $util.dynamodb.toDynamoDBJson(${ctx.args.filter})
}
},
## Add 'limit' and 'nextToken' arguments to implement pagination **
"limit": $util.defaultIfNull(${ctx.args.count}, 3),
"nextToken": $util.toJson($util.defaultIfNullOrBlank(${ctx.args.nextToken}, null))
}
我们的响应解析器:
{
## Change default return field (items) to appropriate PaginatedCountries field **
"countryRefs": $util.toJson($ctx.result.items),
"nextToken": $util.toJson($util.defaultIfNullOrBlank($context.result.nextToken, null))
}
问题
当我们用这样的东西查询时:
getCountryList(filter: $filter) {
countryRefs {
name
locationID
officialName
}
nextToken
}
当filter
用户输入字符时,var 的值会发生变化——例如,,$filter = A
然后$filter = Au
,然后$filter = Aus
,等等——我们得到非常奇怪的返回。在几乎所有情况下,我们似乎都会得到这样的结果:
{
"data": {
"getCountryList": {
"countryRefs": [],
"nextToken": "eyJ2ZXJzaW9uIjoxLCJ0b2..." // a very long string token
}
}
}
奇怪的是,如果我们使用nextToken
我们会在结果的第二页或第三页中找到我们正在寻找的结果:
{
"data": {
"getCountryList": {
"countryRefs": [
{
"locationID": "AUS",
"name": "Australia"
},
{
"locationID": "AUT",
"name": "Austria"
}
],
"nextToken": "eyJ2ZXJzaW9uIjoxLCJ0b2..." // another very long string token
}
}
}
假设
我们花了太多时间认为这是我们的过滤器表达式的问题(可能contains
是问题还是可能begins_with
是问题?)。但是,我们注意到的是,如果我们将limit
(默认值3
或通过客户端提供的count
)更改为通常大于查询中返回的元素数组的预期大小 - 也就是说,之前过滤器表达式应用于结果 - 问题似乎不存在。
例如,使用filter: 'Au'
,如果我们将默认限制设置为200
而不是3
,我们得到的正是我们应该得到的(只有两个以 'Au' 开头的国家名称)!
我的问题是:为什么limit
显然返回了我将要调用的具有“隐藏”值的数组?我的猜测是,除了找到过滤器匹配的索引之外,返回的总返回大小带有一堆空值。无论哪种方式,为什么我们没有以预期的方式获得回报?为什么在limit
这里过滤的不仅仅是回报的数量——即回报的实际结构方式?
任何帮助将不胜感激!