DynamoDB index creation

DynamoDB index creation on existing table

DynamoDB supports two types of indexes.

  • Local Secondary Indexes (LSI)
  • Global Secondary Indexes (GSI)

Once you have created a table either using CLI or from your application, you can only create a Global Secondary Index.

Local Secondary Indexes cannot be created after table has been created.

How table was created

Assuming you created a table which had only partition key id defined during the table creation as follows.

var AWS = require("aws-sdk");

AWS.config.update({
  region: "us-west-2",
  endpoint: "http://localhost:8000"
});

var dynamodb = new AWS.DynamoDB();

var params = {
    TableName : "Movies",
    KeySchema: [       
        { AttributeName: "id", KeyType: "HASH"},  //Partition key
    ],
    AttributeDefinitions: [       
        { AttributeName: "year", AttributeType: "N" },
        { AttributeName: "title", AttributeType: "S" }
    ],
    ProvisionedThroughput: {       
        ReadCapacityUnits: 10, 
        WriteCapacityUnits: 10
    }
};

dynamodb.createTable(params, function(err, data) {
    if (err) {
        console.error("Unable to create table. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Created table. Table description JSON:", JSON.stringify(data, null, 2));
    }
});

Creating table with index using code

We will create a composite key, which is a combination of partition key and sort key.

You can create the index at the time of table creation by adding an attribute of type "RANGE".

{ AttributeName: "title", KeyType: "RANGE"}, //Sort key

var AWS = require("aws-sdk");

AWS.config.update({
  region: "us-west-2",
  endpoint: "http://localhost:8000"
});

var dynamodb = new AWS.DynamoDB();

var params = {
    TableName : "Movies",
    KeySchema: [       
        { AttributeName: "id", KeyType: "HASH"},  //Partition key
        { AttributeName: "title", KeyType: "RANGE"},  //Sort key
    ],
    AttributeDefinitions: [       
        { AttributeName: "year", AttributeType: "N" },
        { AttributeName: "title", AttributeType: "S" }
    ],
    ProvisionedThroughput: {       
        ReadCapacityUnits: 10, 
        WriteCapacityUnits: 10
    }
};

dynamodb.createTable(params, function(err, data) {
    if (err) {
        console.error("Unable to create table. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Created table. Table description JSON:", JSON.stringify(data, null, 2));
    }
});

Creating index on existing table using CLI

For an existing table you can create an GSI. Limit on number of GSI per table currrently is 20.

To create the index you can define params in a json file gsi-movies-title-index.json as follows:

[
  {
    "Create": {
      "IndexName": "MoviesTitleIndex",
      "KeySchema": [
        { AttributeName: "id", KeyType: "HASH"},  //Partition key
        { AttributeName: "title", KeyType: "RANGE"},  //Sort key
      ],
      "ProvisionedThroughput": {
        "ReadCapacityUnits": 1,
        "WriteCapacityUnits": 1
      },
      "Projection": {
        "ProjectionType": "ALL"
      }
    }
  }
]

Now create the GSI using the following command:

aws dynamodb update-table \
    --endpoint-url http://localhost:8000 \
    --table-name Movies \
    --attribute-definitions AttributeName=id,AttributeType=S \
    --attribute-definitions AttributeName=title,AttributeType=S \
    --global-secondary-index-updates file://gsi-movies-title-index.json

If there are no validation errors, the command will complete successfully.

Hope this was useful. Do let me know through your comments.

Reference: AWS Documentation