In DynamoDb, is there a way to atomically check a secondary index for an item before writing it?

579 Views Asked by At

I've got an object like this:

{
     "id": (UUID generated at call time)
     "referenceId": (Foreign key for another system) 
     "referenceType": (enum) 
}

The primary index is just

  • Primary key: id

And I've got a secondary index like

  • Primary key: referenceId
  • Secondary key: referenceType

So what I want to do, is query the secondary index with the referenceId and referenceType, and then if that's empty, write the record to the table.

The problem is, Conditional Expressions can only check same index you're querying. And I've looked into DynamoDb Transactions, but they say you can't have two transactions target the same item.

Is there a way to make this work?

2

There are 2 best solutions below

0
On

As I understand the question, your table PK is generated "at call time" so it would be different for two different requests with the same reference ID and reference type.

That being the case, your answer is no.

If you've got a requirement for uniqueness of a key set by a foreign system, you should consider using the same key or some mashup of it for your DDB table.

Alternately, modify the foreign system to set the UUID for a given reference ID & type.

0
On

If I understand your question correctly, your item has three attributes: id, referenceId and referenceType. You've also defined a global secondary index with a composite primary key of referenceId and referenceType.

Assuming all these attributes are part of the same item, you shouldn't need to read the secondary index before deciding to write to the table. Rather, you could perform a PUT operation on the condition that referenceId and reference type don't yet exist on that item.

ddbClient.putItem({
    "TableName": "YOUR TABLE NAME",
    "Item": { "PK": "id" },
    "ConditionExpression": "attribute_exists(referenceId) AND attribute_exists(referenceType)"
  })

You may also want to check out this fantastic article on DynamoDB condition expressions.