DynamoDB возвращает null nextToken, когда в базе данных еще есть результаты - PullRequest
1 голос
/ 04 февраля 2020

У меня есть API-интерфейс GraphQL (AppSyn c), поддерживаемый таблицей DynamoDB, в котором задан идентификатор c с меткой времени в качестве ключа диапазона. Я хочу получить всю возможную историю для этого идентификатора, поэтому я написал запрос в моей схеме GraphQL, который позволил бы мне это сделать. Вот запрос vtl:

{
    "version": "2017-02-28",
    "operation": "Query",
    "query": {
        "expression": "id = :id",
        "expressionValues": {
            ":id": {
                "S": "$context.args.id"
            }
        }
    },
    "nextToken": $util.toJson($util.defaultIfNullOrEmpty($context.args.nextToken, null))
}

В таблице ddb могут быть тысячи элементов для идентификатора, поэтому я написал лямбда-функцию, чтобы запросить их все и вернуть результат в виде списка как такового (я знаю, что код может быть упрощен):

exports.handler = async function (event, context, callback) {
    const graphqlClient = new appsync.AWSAppSyncClient({
        url: process.env.APPSYNC_ENDPOINT,
        region: process.env.AWS_REGION,
        auth: {
            type: 'AWS_IAM',
            credentials: {
                accessKeyId: process.env.AWS_ACCESS_KEY_ID,
                secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
                sessionToken: process.env.AWS_SESSION_TOKEN
            }
        },
        disableOffline: true
    });

    const query = gql`query GetAllItemsById(
        $id: String!
        $nextToken: String
    ) {
        getAllItemsById(
            id: $id
            nextToken: $nextToken
        ) {
            exampleField {
                subField1
                subField2
                subField3
            }
            nextToken
        }
    }
    `;

    const initialResult = await graphqlClient.query({
        query,
        variables: {
            id: event.id
        }
    });

    var finalResult = initialResult.data.getAllItemsById.exampleField;
    var nextToken = initialResult.data.getAllItemsById.nextToken;

    while (nextToken !== null) {
        const result = await graphqlClient.query({
            query,
            variables: {
                id: event.id,
                nextToken: nextToken
            }
        });

        finalResult = finalResult.concat(result.data.getAllItemsById.exampleField);
        nextToken = result.data.getAllItemsById.nextToken;
    }

    console.log("Total Results: " + finalResult.length);

    return callback(null, finalResult);
};

По некоторым причинам, не все предметы возвращаются. nextToken равно нулю, прежде чем будут возвращены все результаты. Я знаю, что DDB имеет ограничение в 1 МБ для запроса, поэтому я делаю нумерацию страниц с использованием nextToken, но почему он до сих пор не возвращает все элементы в таблице? Кроме того, если есть лучший способ реализовать это, я открыт для этого.

...