2017-09-20 3 views
0

Quelqu'un pourrait me dire comment définir une carte comme valeur pour un attribut qui n'existe pas encore. J'ai essayé une expression de mise à jour "SET MyAttr.#key = :val", mais cela ne fonctionne que si l'attribut existe et si la valeur de l'attribut est déjà une carte.Comment insérer une carte comme valeur d'attribut lorsque l'attribut n'existe pas encore avec DynamoDB?

J'ai essayé d'utiliser à la place "ADD MyAttr.#key = :val", mais je reçois:

UpdateExpression non valide: Erreur de syntaxe; jeton: "=", près: "#key =: val"

J'utilise Java. Notez que j'utilise une tentative d'une requête UpdateItem pour le faire. Il m'est juste venu à l'esprit que cela ne fonctionne peut-être pas avec les cartes. J'ai juste supposé que ce serait parce que j'ai toujours pu avoir un nouvel élément et/ou attribut créé avec une demande de mise à jour s'il n'existe pas déjà (avec d'autres types de données de valeur d'attribut comme chaîne, nombre, etc.).

Répondre

1

Supposons que nous avons l'article suivant dans notre DynamoDB Tableau:

{ 
    "id": "91c2b60d-c428-403c-be42-8657b4f20669", 
    "firstName": "John", 
    "lastName": "Doe" 
} 

et nous voulons ajouter des attributs personnalisés que nous avons une carte:

Map<String, String> customAttributes = new HashMap<>(); 
customAttributes.put("age", "21"); 
customAttributes.put("gender", "Male"); 

AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); 
DynamoDB dynamodb = new DynamoDB(client); 

Table table = dynamodb.getTable("users"); 
UpdateItemSpec updateItemSpec = new UpdateItemSpec() 
      .withPrimaryKey("id", "91c2b60d-c428-403c-be42-8657b4f20669") 
      .withUpdateExpression("set #customAttributes = :customAttributes") 
      .withNameMap(new NameMap().with("#customAttributes", "customAttributes")) 
      .withValueMap(new ValueMap().withMap(":customAttributes", customAttributes)) 
      .withReturnValues(ReturnValue.ALL_NEW); 

UpdateItemOutcome outcome = table.updateItem(updateItemSpec); 
System.out.println(outcome.getItem().toJSONPretty()); 

Le résultat:

{ 
    "id" : "91c2b60d-c428-403c-be42-8657b4f20669", 
    "firstName" : "John", 
    "lastName" : "Doe", 
    "customAttributes" : { 
    "gender" : "Male", 
    "age" : "21" 
    } 

}

Maintenant, si nous voulons ajouter un nouvel attribut à la carte CustomAttributes:

UpdateItemSpec updateItemSpec = new UpdateItemSpec() 
    .withPrimaryKey("id", "91c2b60d-c428-403c-be42-8657b4f20669") 
    .withUpdateExpression("set customAttributes.#occupation = :value") 
    .withNameMap(new NameMap().with("#occupation", "occupation")) 
    .withValueMap(new ValueMap().withString(":value", "Programmer")) 
    .withReturnValues(ReturnValue.ALL_NEW); 

UpdateItemOutcome outcome = table.updateItem(updateItemSpec); 

System.out.println(outcome.getItem().toJSONPretty()); 

Je vous suggère de jeter un oeil à: DynamoDBMapper, il vous permettra d'économiser des tonnes de lignes de code.

+0

Cela répond à la question que j'ai posée et cela fonctionne. Mais est-il possible d'effectuer une mise à jour par laquelle Dynamo va ajouter à la carte si elle existe déjà? La solution que vous avez fournie écrasera toute carte existante. Ou dois-je d'abord rechercher l'élément, puis créer un UpdateItemSpec différent selon que l'élément/attr existe ou non? – RTF

+1

Oui, c'est possible! Je vais éditer ma réponse pour vous montrer un exemple. –

+0

Merci pour la mise à jour, mais ce que je cherche est une mise à jour one-shot qui sera soit a). Créez une carte avec ma paire clé/valeur et définissez la carte comme valeur de mon attribut, si l'élément et/ou l'attribut n'existe pas encore, ou b). mettre à jour la carte existante dans mon attribut avec la paire clé/valeur spécifiée. Je pense que ce n'est pas possible dans une seule demande cependant: https://stackoverflow.com/questions/35377729/how-to-set-a-dynamodb-map-property-value-when-the-map-doesnt-exist- encore? rq = 1 – RTF