web-dev-qa-db-fra.com

Est-il possible de faire un put ou une mise à jour conditionnelle dans DynamoDB?

Disons que je stocke des enregistrements avec la structure suivante dans DynamoDB:

{    
    "id": "57cf5b43-f9ec-4796-9de6-6a50f556cfd8",
    "created_at": "2015-09-18T13:27:00+12:00",
    "count": 3
}

Maintenant, est-il possible de réaliser ce qui suit en une seule demande:

  • si l'enregistrement avec id n'existe pas, il doit être créé avec count = 1
  • si l'enregistrement pour ce id existe, le compteur est mis à jour.

Actuellement, je fais une requête pour vérifier si l'enregistrement existe et selon le résultat, je fais un put ou un update. Ce serait bien de plier cela en une seule opération.

25
Piotr Zurek

Vous pouvez le faire avec UpdateItem API et UpdateExpression en raison de votre cas d'utilisation. Puisque count sera un type Number ici, vous pouvez utiliser les expressions SET ou ADD:

La documentation de ADD vous indique que vous pouvez l'utiliser pour les types Number (le mien est souligné):

  • ADD - Ajoute la valeur spécifiée à l'élément, si l'attribut n'existe pas déjà. Si l'attribut existe, le comportement d'ADD dépend du type de données de l'attribut:

    • Si l'attribut existant est un nombre, et si Value est également un nombre, alors Value est mathématiquement ajouté à l'attribut existant. Si Value est un nombre négatif, il est soustrait de l'attribut existant.

    Si vous utilisez ADD pour incrémenter ou décrémenter une valeur numérique pour un élément qui n'existait pas avant la mise à jour, DynamoDB utilise 0 comme valeur initiale. De même , si vous utilisez ADD pour un élément existant pour incrémenter ou décrémenter une valeur d'attribut qui n'existait pas avant la mise à jour, DynamoDB utilise 0 comme valeur initiale. Par exemple, supposons que l'élément que vous souhaitez mettre à jour ne possède pas d'attribut nommé itemcount, mais vous décidez néanmoins d'ajouter le numéro 3 à cet attribut. DynamoDB créera l'attribut itemcount, définira sa valeur initiale à 0 et y ajoutera finalement 3. Le résultat sera un nouvel attribut itemcount dans l'article, avec une valeur de 3.

Pour votre exemple, vous pourriez avoir votre UpdateExpression être ADD #c :n, où :n a un ExpressionAttributeValue du type Number, 1 est la valeur et #c a la substitution ExpressionAttributeName pour count. Vous devez utiliser un espace réservé pour count car il s'agit d'un mot réservé .

Voir plus d'exemples sur le Modification des éléments et des attributs avec des expressions de mise à jour

18
mkobit

Ce que je n'ai pas mentionné dans ma question, c'est que je voulais que le count monte pour les événements ultérieurs sans modifier le created_at. Mon UpdateInput de travail final ressemble à ça:

{
  Key: {
    id: {
      S: "some_unique_id"
    }
  },
  TableName: "test",
  ExpressionAttributeNames: {
    #t: "created_at",
    #c: "count"
  },
  ExpressionAttributeValues: {
    :t: {
      S: "2015-09-26T15:58:57+12:00"
    },
    :c: {
      N: "1"
    }
  },
  UpdateExpression: "SET #t = if_not_exists(#t, :t) ADD #c :c"
}
16
Piotr Zurek