Я пытаюсь создать запрос AWS AppSync со списком с помощью 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 в качестве параметра и получить результаты, идентификаторы которых входят в число предоставленных параметров?
Обновлено: Исправлена опечатка в имени переменной.





Я думаю, здесь может быть 2 проблемы:
Ваши аргументы в запросе listItemsWithIdList принимают аргумент с именем userIds. У вас есть $ctx.args.ids) в вашем шаблоне Resolver. Вам нужно использовать одно и то же имя аргумента в обоих местах.
Когда вы используете $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. Вы можете передать список ключей в одном запросе и вернуть результаты из таблицы.
## 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)
Спасибо за подход, но я избегаю использования раздела filter, поскольку он может испортить результаты при использовании с разбивка на страницы. Вы пробовали contains в выражение запроса, т.е. именно там, где author = :author в вашем первом фрагменте.
@vahdet Надеюсь, это пригодится!
BatchGetItem выглядит неплохо, но я сомневаюсь в производительности. Собираюсь проверить это. Для разбивки на страницы используется другой подход, кстати: UnprocessedKeys
Надеюсь, вы уже решили это. Однако в вашей настройке есть две проблемы:
Это должно быть выражение фильтра, и, поскольку у вас нет ключевого условия, это может быть даже сканирование вместо запроса.
Затем возникают проблемы с синтаксисом (именно из-за этого на самом деле возникает ошибка): В ВЫРАЖЕНИИ добавьте круглые скобки к переменной "выражение": "идентификатор IN (: ids"),
И в EXPRESSION VALUES используйте toStringSetJson вместо toStringSet "expressionValues": {": ids": $ util.dynamodb.toStringSetJson ($ ctx.args.ids)}
Надеюсь это поможет.
Спасибо, причина, по которой я избегал Scan, заключалась в том, что его filter применяется после разбивки на страницы (см. Использование limit и nextToken в OP). Вы не можете прилично получить первым, скажем, 5 результатов, он может вернуть 3 из 10 с Scan.
Спасибо, я удалил двусмысленность, вызванную userIds / ids из вопроса. Пробовал
$util.dynamodb.toStringSetJson, но потом ошибка сталаInvalid KeyConditionExpression: Syntax error; token: \":userIds\", near: \"IN :userIds. Думаю,INне разрешен для запроса, этот ссылка также говорит об этом.