3
votes

We're having a lot of trouble doing a partial update in DynamoDB.

Trying to use best practices in NoSQL by using aggregates instead of entities so our data looks a bit like this:

[
{
    "userLogin": {
        "ipAddress": "123.222.121.1234",
        "lastLogin": "2017-10-16T17:38:59.818Z",
        "userAgent": "bob",
        "geoLocation": "lat-121 long-312"
    },
    "addresses": {
        "billingAddress": {
            "streetName": "york street",
            "province": "ontario",
            "city": "toronto",
            "streetNumber": "18",
            "postalCode": "m5a2v7"
        },
        "businessAddress": {
            "streetName": "york street",
            "province": "ontario",
            "city": "toronto",
            "streetNumber": "18",
            "postalCode": "m5a2v7"
        },
        "mailingAddress": {
            "streetName": "york street",
            "province": "ontario",
            "city": "toronto",
            "streetNumber": "18",
            "postalCode": "m5a2v7"
        },
    },
    "paymentTransaction": {
        "orderId": 5,
        "amount": 75,
        "transactionTimestamp": "2017-10-16T17:38:59.818Z"
    },
    "userId": "00uc4sxyi7gfQoFum0h7",
    "phoneNumbers": {
        "workNumber": "647-123-1234",
        "homeNumber": "647-321-4321"
    },
    "userProfile": {
        "role": "admin",
        "verifiedTimeStamp": "2017-10-16T17:38:59.818Z",
        "termsConditionTimeStamp": "2017-10-16T17:38:59.818Z",
        "verified": "TRUE",
        "createdTimeStamp": "2017-10-16T17:38:59.818Z",
        "termsConditionVersion": "1.0",
        "email": "[email protected]"
    }
}

]

All we want to do is make a request with a body like this:

PUT /api/user-profiles/00uc4sxyi7gfQoFum0h7
body: {
    "userLogin": { "lastLogin": "2017-12-16T17:38:59.818Z" }
}

and have it update the one attribute in the User table.

The updateItem API seems to require defining the attributes you want to update before updating them, but we want it be more flexible and dynamic based on the body of the request.

This thread seems to say it's not possible:

How to update multiple items in a DynamoDB table at once

If so, what's the best way to go about updating just a partial attribute object within an item in DynamoDB?

1

1 Answers

3
votes

In dynamoDB if your userLogin is a map type then you can update the value of lastLoginkey. In Java below code may help. Here column name would be userLogin and newKey would be lastLogin. Full code snippet can be found here

UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey(primaryKey,primaryKeyValue).withReturnValues(ReturnValue.ALL_NEW).
        withUpdateExpression("set #columnName." + newKey + " = :columnValue").
        withNameMap(new NameMap().with("#columnName", updateColumn)).
        withValueMap(new ValueMap().with(":columnValue", newValue)).withConditionExpression("attribute_exists("+ updateColumn +")");

table.updateItem(updateItemSpec);