Iliaaaa
Iliaaaa

Reputation: 119

Removing data without primary index DynamoDB

currently i am using dynamodb for storing connection id's of aws websockets, and i am using them as primary index for my documents, overall my schema looks like this

{
      ID: connectionId,
      userId: userId,
      domainName,
      stage,
}

everything is okay with this schema, just one problem, i have an sns topic that dispatches user id to this api endpoint, and i need to delete every connection with that userId, i was looking into batchWrite but it requires me to use userId as primary index rather than connectionId, i chose this schema type because it is flexible, i can easily find documents with connection id when user disconnects and delete with one command, and add it as well, is there option for me to batchwrite without primary key? second option is to transform schema as this

{  
      ID: userId,
      connections: [
          {
              connectionId: connectionId,
              stage,
              domainName
          }
      ],
}

which i am not so keen of, is this the only other option?

Upvotes: 1

Views: 150

Answers (1)

Mhamd Bahja
Mhamd Bahja

Reputation: 157

You need to change the DB schema by the following:

For the primary index

connectionId: partition key

Create global secondary index:

userId: partition key

First scenario:

When you need to delete all connections belonging to userId you need to query using userId and then run batchWrite command to delete all rows

Query using GSI:

const items = ddb.query({
    TableName: "connections",
    IndexName: "globalSecondaryIndexNameHere",
    KeyConditionExpression: "userId = :userId",
    ExpressionAttributeValues: {
        ":userId": "abc"
    }
})

Then loop throw items and make batchWrite request to delete:

ddb.batchWrite({
    RequestItems: {
        "connections": [
            {
                DeleteRequest: {
                    Key: {
                        "connectionId": "connectionId1"
                    }
                }
            },
            {
                DeleteRequest: {
                    Key: {
                        "connectionId": "connectionId2"
                    }
                }
            },
            // ...
        ]
    }
})

Second scenario:

When you need to delete one row by connectionId

Delete:

ddb.deleteItem({
    TableName: "connections",
    Key: {
        "connectionId": "connectionId1"
    }
})

NOTE: I recommend using AWS AppSync instead of API Gateway, since appsync manages your connectionIds instead of saving them in DynamoDB plus many other reasons stated HERE

Upvotes: 1

Related Questions