Динамо БД: обновление атрибута списка - PullRequest
0 голосов
/ 31 октября 2019

Я разрабатываю приложение на основе викторин для AWS, используя безсерверный фреймворк через AWS Amplify. База данных, используемая для этого приложения, - DynamoDB.

Я пытаюсь сохранить список пользовательских ответов в виде записи в базе данных. Прямо сейчас у меня есть ключ раздела (с именем "type") как quizDraftAnswers_{user-id}, поэтому я могу быстро получить записи на основе идентификатора пользователя. У меня также есть ключ сортировки (с именем "id") как category_{category-id}#subCategory_{subcategory-id}. В создаваемой мной викторине вопросы разбиты на категории и подкатегории. Для более быстрого извлечения данных я подумал, что это будет наилучшим способом разработки ключа сортировки.

Запись тогда имеет атрибут questions в качестве типа списка. Этот атрибут содержит список идентификаторов вопросов и их ответов на карте.

Это пример структуры данных:

{
  "id": "category_89#subCategory_90",
  "questions": [
    {
      "id": "101",
      "answerId": "1"
    },
    {
      "id": "102",
      "answerId": "3"
    },
    {
      "id": "103",
      "answerId": "5"
    },
    {
      "id": "104",
      "answerId": "3"
    }
  ],
  "type": "quizDraftAnswers_74527"
}

Я создал API, который отправляет userId,category, subCategory, questionId и answerId для функции Lambda, которая выполняет некоторый динамо-код NodeJS.

Проблема, с которой я столкнулся при работе с DynamoDB, заключается в том, как мне обновитьсписок вопросов?

Например, если это первый вопрос, на который пользователь отвечает, как бы мне создать первоначальную запись (id, type, question[], содержащую карту с id иanswerId)? Как добавить новый ответ в конец списка вопросов? Если пользователь изменит свой ответ, как мне обновить его в списке вопросов?

Это лямбда-функция, которая у меня есть:

exports.updateAnswer = (employeeId, categoryId, subCategoryId, questionId, answerId) =>
  new Promise(async resolve => {
    const params = {
      TableName: tableName,
      Key: {
        type: `quizDraftAnswers_${employeeId}`,
        id: `category_${categoryId}#subCategory_${subCategoryId}`
      },
      UpdateExpression: `SET #questions[].:id = :value`,
      ExpressionAttributeNames: {
        '#questions': 'questions'
      },
      ExpressionAttributeValues: {
        ':question': questionId,
        ':value': answerId
      }
    };

    dynamodb.update(params, (err, data) => {
      if (err) {
        resolve({ error: true, message: err });
      } else {
        resolve({ error: false, items: data.Items });
      }
    });
  });

Выражение обновления - это то, что я могу 'Кажется, не могу понять. Я перепробовал много разных вариантов, но всегда получаю какую-то ошибку. Мне было интересно, есть ли у кого-нибудь предложения о том, как правильно написать этот код.

1 Ответ

0 голосов
/ 01 ноября 2019

Вам нужно использовать функцию list_append для добавления новых элементов в список. Подробнее об этом здесь ( Добавление элементов в список * секция 1005 *)

Таким образом, ваши параметры будут выглядеть следующим образом

const params = {
  TableName: tableName,
  Key: {
    type: `quizDraftAnswers_${employeeId}`,
    id: `category_${categoryId}#subCategory_${subCategoryId}`
  },
  UpdateExpression: `SET #questions = list_append(if_not_exists(#questions, :empty_list), :value)`,
  ExpressionAttributeNames: {
    '#questions': 'questions'
  },
  ExpressionAttributeValues: {
    ':empty_list': [],
    ':question': questionId,
    ':value': answerId
  }
};

Как следует из названия,if_not_exists функция проверяет наличие списка. Если это не просто добавить пустой список [], иначе добавьте новое значение в существующий список.

...