Reputation: 2098
I have a dynamoDB entry where each item has a rating
property. I am incrementing the value using an atomic counter using the following expression:
UpdateExpression: 'set info.rating = info.rating + :val',
Is there a way I can limit the maximum rating value without having to read, check the current value against the existing, and then write only if it does not exceed the limit I have set?
Something like the following would be ideal:
UpdateExpression: 'if (!(info.rating + :val)) set info.rating = info.rating + :val',
Thanks
Upvotes: 0
Views: 377
Reputation: 13983
DynamoDB documents don't have fixed schema beyond your partition and sort keys, so there's no way to apply a constraint to a field.
Unfortunately, you also can't perform an 'increment with cap' in a single operation. DynamoDB's update expression support for real-world applications is very poor.
You can take advantage of condition expressions to stop the update if it would exceed the cap:
UpdateExpression: 'SET info.rating = info.rating + :val',
ConditionExpression: 'info.rating <= :maxAllowed' // Where :maxAllowed = :cap - :val
If this results in a conditional check failure, you know that adding to the existing value would exceed the cap, so you can perform another operation to attempt to set it to the cap:
UpdateExpression: 'SET info.rating = :cap',
ConditionExpression: 'info.rating > :maxAllowed'
If this fails again, you can loop back and retry the first operation, because something decremented the value between the operations.
However, if your use case expects the increment to often hit the cap, you may find it cheaper to just perform a read and write, as it's significantly cheaper than two writes. You should still use a condition expression to ensure that the write doesn't exceed the cap.
Upvotes: 3