2016-07-08 7 views
0

Ich verwende DynamoDBMapper aus dem AWS Java SDK und arbeiten mit einem ziemlich einfachen Element: Es hat ein String-Attribut (als Hash-Schlüssel verwendet) und ein Kartenattribut.Aktualisieren Sie vorhandenen Eintrag innerhalb eines Kartenattributs mit DynamoDBMapper

@DynamoDBTable(tableName = "MyTable") 
public class MyItem { 
    private String myStringAttr; 
    private Map<String, String> myMapAttr; 

    @DynamoDBHashKey(attributeName = "MyStringAttribute") 
    public String getMyKeyAttr() { return myKeyAttr; } 
    public void setMyKeyAttr(String myKeyAttr) { this.myKeyAttr = myKeyAttr; } 

    @DynamoDBAttribute(attributeName = "MyMapAttribute") 
    public Map<String, String> getMyMapAttr() { return myMapAttr; } 
    public void setMyMapAttr(Map<string, string> myMapAttr) { this.myMapAttr = myMapAttr; } 
} 

Ich kann meine Aufgabe mit den load() und save() Methoden ganz gut lesen und schreiben. Das Problem, auf das ich stoße, ist, wenn ich einen einzelnen Eintrag in der Map für ein vorhandenes Element in der Tabelle aktualisieren oder hinzufügen muss. Ohne die vorhandenen Einträge der Karte für diesen Gegenstand zu kennen (und ich möchte nicht jedesmal eine load() durchführen, bevor ich versuche, sie zu aktualisieren oder hinzuzufügen), scheint es mir am besten zu sein, die gesamte Karte auszulöschen und zu ersetzen es mit dem einzelnen Eintrag versuche ich zu aktualisieren oder hinzuzufügen. Ist es möglich, mit dem DynamoDBMapper einen einzelnen Eintrag zum Map-Attribut eines vorhandenen Elements hinzuzufügen/zu aktualisieren?

Ich habe mir die verschiedenen Optionen von DynamoDBSaveExpression und DynamoDBMapperConfig angesehen. Die nächste Option, die ich finden kann, ist DynamoDBMapperConfig.SaveBehavior.APPEND_SET, aber das ist für Set-Typ-Attribute und nicht für den Kartentyp, den ich verwende.

Ich bin in der Lage, diesen genauen Anwendungsfall mit der Methode updateItem() der Dokument-API zusammen mit einer UpdateItemSpec zu erreichen, die eine UpdateExpression wie unten gezeigt enthält. Dies fügt der Map einen neuen Eintrag hinzu, wenn der angegebene Schlüssel noch nicht existiert, oder aktualisiert den Wert auf den spezifischen Wert, wenn ein existierender Eintrag vorhanden ist, ohne die anderen Einträge in der Map zu berühren. Allerdings habe ich festgestellt, dass die Document API eher umständlich zu handhaben ist und lieber bei der DynamoDBMapper bleiben würde, wenn überhaupt möglich.

Table table = dynamoDB.getTable("MyTable"); 

UpdateItemSpec updateItemSpec = new UpdateItemSpec() 
    .withPrimaryKey("MyStringAttribute", 1) 
    .withUpdateExpression("set #mma.#mek = :mev") 
    .withNameMap(new NameMap() 
     .with("#mma", "MyMapAttribute") 
     .with("#mek", "SomeMapEntryKey") 
    .withValueMap(new ValueMap() 
     .withString(":mev", "Some map entry value")); 

UpdateItemOutcome outcome = table.updateItem(updateItemSpec); 

Antwort

0

Eine mögliche Lösung wäre: -

1) Holen Sie sich die Daten aus der Tabelle "MyTable" DynamoDBMapper Last

2) Fügen Sie neue Einträge in der Karte in der in Schritt abgerufene Objekt mit 1 und das Objekt mit DynamoDBMapper mit Config speichern, wie unten

DynamoDBMapperConfig dynamoDBMapperConfig = new DynamoDBMapperConfig(SaveBehavior.UPDATE); 

erwähnte ich weiß, dass dies ein zweistufiger Prozess ist. Als ich jedoch in der gleichen Situation war, habe ich viel versucht und konnte keine Lösung mit einer einzigen direkten Aktualisierung für den Datentyp "Map" mit DynamoDBMapper finden.

Hoffe, das hilft!

+0

Ich würde es vorziehen, mehrere Schritte zu vermeiden, da es keine Transaktion gibt, die ich verwenden kann, um diese beiden Operationen zu umbrechen. – nalapoke