Сопоставить разные ответы ключа сортировки со значениями схемы Appsync - PullRequest
0 голосов
/ 27 августа 2018

Так вот моя схема:

type Model {
    PartitionKey: ID!
    Name: String
    Version: Int
    FBX: String
    # ms since epoch
    CreatedAt: AWSTimestamp
    Description: String
    Tags: [String]
}

type Query {
    getAllModels(count: Int, nextToken: String): PaginatedModels!
}

type PaginatedModels {
    models: [Model!]!
    nextToken: String
}

Я хотел бы вызвать 'getAllModels' и получить все его данные, а также заполнить все его теги.

Но вот в чем дело. Теги хранятся с помощью ключей сортировки. Вот так

PartionKey | SortKey
Model-0    | Model-0
Model-0    | Tag-Tree
Model-0    | Tag-Building

Можно ли преобразовать ключи сортировки 'Tag' в массив Tags: [String] в схеме с помощью преобразователя DynamoDB? Или я должен сделать что-то необычное через лямбду? Или есть более разумный способ сделать это?

1 Ответ

0 голосов
/ 28 августа 2018

Чтобы уточнить, храните ли вы такие объекты в DynamoDB:

{ PartitionKey (HASH), Tag (SortKey), Name, Version, FBX, CreatedAt, Description }

и использование операции DynamoDB Query для извлечения всех строк для заданного HashKey.

Query #PartitionKey = :PartitionKey

и возвращаем список объектов, некоторые из которых имеют другое значение «Tag», а один - «Model-0» (то же самое, что и ключ разделения), и я предполагаю, что запись содержит все другие значения для запись. Е.Г.

[
  { PartitionKey, Tag: 'ValueOfPartitionKey', Name, Version, FBX, CreatedAt, ... },
  { PartitionKey, Tag: 'Tag-Tree' },
  { PartitionKey: Tag: 'Tag-Building' }
]

Вы определенно можете написать логику распознавателя без особых хлопот, которые сводят список объектов модели в один объект со списком «Тегов». Давайте начнем с одного элемента и посмотрим, как реализовать запрос getModel(id: ID!): Model:

Сначала определите шаблон отображения ответа, который получит все строки для ключа раздела:

{
    "version" : "2017-02-28",
    "operation" : "Query",
    "query" : {
        "expression": "#PartitionKey = :id",
        "expressionValues" : {
            ":id" : {
                "S" : "${ctx.args.id}"
            }
        },
        "expressionNames": {
          "#PartitionKey": "PartitionKey" # whatever the table hash key is
        }
    },
    # The limit will have to be sufficiently large to get all rows for a key
    "limit": $util.defaultIfNull(${ctx.args.limit}, 100)
}

Затем, чтобы вернуть один объект модели, который уменьшает «Tag» до «Tag», вы можете использовать этот шаблон отображения ответа:

#set($tags = [])
#set($result = {})
#foreach( $item in $ctx.result.items )
    #if($item.PartitionKey == $item.Tag)
      #set($result = $item)
    #else
        $util.qr($tags.add($item.Tag))
    #end
#end
$util.qr($result.put("Tags", $tags))
$util.toJson($result)

Это вернет ответ, подобный этому:

{
  "PartitionKey": "...",
  "Name": "...",
  "Tags": ["Tag-Tree", "Tag-Building"],
}

Принципиально я не вижу проблем с этим, но его эффективность зависит от ваших шаблонов запросов. Расширение этого до использования getAll выполнимо, но потребует нескольких изменений и, скорее всего, действительно неэффективной операции сканирования из-за того, что в таблице будет мало фактической информации, поскольку многие записи фактически являются просто тегами. Вы можете облегчить это с помощью GSI, но больше GSI означает больше $.

В качестве альтернативного подхода вы можете хранить свои теги в другой таблице тегов. Таким образом, вы только сохраняете информацию о модели в таблице Model и информацию о тегах в таблице Tag и используете GraphQL для выполнения объединения. В этом подходе Query.getAllModels выполняет «Сканирование» (или запрос) таблицы модели, а затем имеет преобразователь Model.Tags , который выполняет запрос к таблице тегов (HK). : ModelPartitionKey, SK: Tag). Затем можно получить все теги для модели, а затем создать GSI, чтобы получить все модели для тега. Вы должны учитывать, что теперь вложенный запрос Model.Tag будет вызываться один раз для каждой модели, но операции запроса выполняются быстро, и я видел, как это хорошо работает на практике.

Надеюсь, это поможет:)

...