Симуляция оператора IN для NoSQL базы данных

Вопрос или проблема

Я хочу смоделировать запрос SELECT * FROM TABLE WHERE ID IN {LIST_OF_IDS}. Я знаю, что использую базу данных NoSQL (dynamoDB), но у меня есть индекс на поле, по которому я хочу выполнить этот запрос. В основном я хочу получить все посты от пользователя, где userID (индексный столбец) находится в данном списке.

Я использую Amplify в качестве управляемого бэкенда и GraphQL в качестве API. Я знаю, что нет ключевого слова IN для использования в GraphQL (по крайней мере, в APPSYNC). Я пытался создать пользовательский резолвер на основе шаблона, предоставленного AWS, вот так:

import { util } from '@aws-appsync/utils';

/**
 * Получает элементы из таблиц DynamoDB партиями с предоставленными ключами `id`
 * @param {import('@aws-appsync/utils').Context} ctx контекст
 * @returns {import('@aws-appsync/utils').DynamoDBBatchGetItemRequest} запрос
 */
export function request(ctx) {
    return {
        operation: 'BatchGetItem',
        tables: {
            Posts: {
                keys: ctx.args.ids.map((id) => util.dynamodb.toMapValues({ id })),
                consistentRead: true,
            },
        },
    };
}

/**
 * Возвращает элементы таблицы BatchGetItem
 * @param {import('@aws-appsync/utils').Context} ctx контекст
 * @returns {[*]} элементы
 */
export function response(ctx) {
    if (ctx.error) {
        util.error(ctx.error.message, ctx.error.type);
    }
    return ctx.result.data.Posts;
}

Но это, похоже, не работает. Я также хотел бы избежать выполнения запроса для каждого пользователя в списке, чтобы получить посты. Буду признателен за любую помощь, а также если у вас есть другое архитектурное решение/предложение для решения этой проблемы, я слушаю!

Ответ или решение

Для решения вашей задачи по эмуляции оператора IN в базе данных NoSQL (в данном случае DynamoDB) при использовании GraphQL и Amplify, действительно можно использовать функцию BatchGetItem, как вы уже пробовали. Но прежде всего, убедитесь, что вы правильно настроили элемент в таблице и определили индекс для поля userID. Давайте разберемся с вашим кодом и оптимизируем решение.

Пример opgelostия

Шаг 1: Настройка таблицы и индексов

Убедитесь, что у вас есть таблица, в которой хранится информация о постах, с соответствующими ключами и индексами. Допустим, у вас есть таблица Posts с ключом id и индексом userID.

Шаг 2: Создание кастомного резолвера

Используйте ваш текущий код, но убедитесь, что вы обрабатываете данные правильно. Вот улучшенный вариант вашего кода:

import { util } from '@aws-appsync/utils';

/**
 * Получает элементы из таблицы DynamoDB в пакетах с заданными ключами `ids`
 * @param {import('@aws-appsync/utils').Context} ctx контекст
 * @returns {import('@aws-appsync/utils').DynamoDBBatchGetItemRequest} запрос
 */
export function request(ctx) {
    return {
        operation: 'BatchGetItem',
        tables: {
            Posts: {
                keys: ctx.args.ids.map(id => util.dynamodb.toMapValues({ id })),
                consistentRead: true,
            },
        },
    };
}

/**
 * Возвращает элементы из BatchGetItem
 * @param {import('@aws-appsync/utils').Context} ctx контекст
 * @returns {[*]} элементы
 */
export function response(ctx) {
    if (ctx.error) {
        util.error(ctx.error.message, ctx.error.type);
    }
    return ctx.result.data.Posts;
}

Шаг 3: Использование резолвера в GraphQL запросе

Теперь вы можете использовать этот резолвер в вашем GraphQL запросе. Например:

query GetPosts($ids: [ID!]!) {
    getPosts(ids: $ids) {
        id
        userID
        content
        createdAt
    }
}

Шаг 4: Передача данных

Не забудьте передать массив ids при вызове этого запроса из вашего фронтенда. Например:

const postIds = ["id1", "id2", "id3"];
const result = await API.graphql(graphqlOperation(getPosts, { ids: postIds }));

Альтернативный подход

Если вы хотите избежать использования BatchGetItem, можно рассмотреть использование Query с индексами. Однако, это будет означать, что требуется выполнять множество запросов, что может оказаться менее эффективным, чем BatchGetItem.

Заключение

Итак, используя метод BatchGetItem в вашем кастомном резолвере, вы сможете эффективно получить данные по нескольким ids без выполнения отдельных запросов для каждого пользователя. Убедитесь, что ваш индекс правильно настроен и что все ключи уникальны для успешного получения данных.

Если у вас возникнут дополнительные вопросы или потребуется помощь с реализацией, не стесняйтесь обращаться!

Оцените материал
Добавить комментарий

Капча загружается...