Create and Query a Global Secondary Index (GSI) in DynamoDB
📖 Scenario: You are building a simple product catalog database using DynamoDB. You want to store products with their ProductID as the main key. Later, you want to quickly find products by their Category using a Global Secondary Index (GSI).
🎯 Goal: Create a DynamoDB table with a primary key ProductID, add a Global Secondary Index (GSI) on Category, and write a query to find all products in a specific category.
📋 What You'll Learn
Create a DynamoDB table named Products with ProductID as the partition key.
Add a Global Secondary Index named CategoryIndex with Category as the partition key.
Insert sample product items with ProductID, Name, and Category attributes.
Write a query using the GSI CategoryIndex to find all products in the category Electronics.
💡 Why This Matters
🌍 Real World
Global Secondary Indexes let you query DynamoDB tables efficiently by attributes other than the primary key, which is common in real-world applications like product catalogs, user profiles, and event logs.
💼 Career
Understanding GSIs is essential for database engineers and backend developers working with DynamoDB to design scalable and performant NoSQL databases.
Progress0 / 4 steps
1
Create the DynamoDB table with primary key
Create a DynamoDB table named Products with ProductID as the partition key of type S (string). Use the AWS CLI command aws dynamodb create-table with the required attributes and key schema.
DynamoDB
Hint
Use the AWS CLI create-table command with --attribute-definitions and --key-schema options.
2
Add a Global Secondary Index (GSI) on Category
Update the Products table creation command to include a Global Secondary Index named CategoryIndex with Category as the partition key of type S. Add --attribute-definitions for Category and define the GSI with --global-secondary-indexes.
DynamoDB
Hint
Remember to add Category to --attribute-definitions and define the GSI with --global-secondary-indexes.
3
Insert sample product items
Insert three product items into the Products table using the AWS CLI put-item command. Use these exact items: 1. {"ProductID": {"S": "P100"}, "Name": {"S": "Smartphone"}, "Category": {"S": "Electronics"}} 2. {"ProductID": {"S": "P101"}, "Name": {"S": "Laptop"}, "Category": {"S": "Electronics"}} 3. {"ProductID": {"S": "P102"}, "Name": {"S": "Coffee Mug"}, "Category": {"S": "Kitchen"}}
DynamoDB
Hint
Use aws dynamodb put-item three times with the exact JSON items.
4
Query products by Category using the GSI
Write an AWS CLI query command to find all products in the Electronics category using the Global Secondary Index CategoryIndex. Use --table-name Products, --index-name CategoryIndex, and a KeyConditionExpression with Category = :cat. Define the expression attribute value :cat as {"S": "Electronics"}.
DynamoDB
Hint
Use aws dynamodb query with --index-name CategoryIndex and the correct key condition expression.
Practice
(1/5)
1. What is the main purpose of a Global Secondary Index (GSI) in DynamoDB?
easy
A. To allow queries using alternate keys different from the primary key
B. To store backup copies of the table data
C. To increase the size limit of the table
D. To encrypt data automatically
Solution
Step 1: Understand what a GSI does
A GSI lets you query the table using different keys than the main primary key.
Step 2: Compare options to GSI purpose
Options A, C, and D describe unrelated features like backup, size, or encryption, which are not GSI functions.
Final Answer:
To allow queries using alternate keys different from the primary key -> Option A
Quick Check:
GSI = alternate query keys [OK]
Hint: GSI lets you search by different keys, not backup or encryption [OK]
Common Mistakes:
Confusing GSI with backups
Thinking GSI increases table size
Assuming GSI encrypts data
2. Which of the following is the correct way to define a Global Secondary Index (GSI) in a DynamoDB table creation JSON?
The GlobalSecondaryIndexes must be an array of objects, each with IndexName, KeySchema, and Projection.
Step 2: Validate key schema and projection
{
"GlobalSecondaryIndexes": [
{
"IndexName": "GSI1",
"KeySchema": [
{"AttributeName": "GSIKey", "KeyType": "HASH"},
{"AttributeName": "SortKey", "KeyType": "RANGE"}
],
"Projection": {"ProjectionType": "INCLUDE", "NonKeyAttributes": ["Attr1"]}
}
]
} correctly uses an array, has both HASH and RANGE keys, and a valid projection with included attributes.
Final Answer:
Correct GSI JSON with array, keys, and projection -> Option D
Quick Check:
GSI JSON array with keys and projection = A [OK]
Hint: GSI must be an array with keys and projection defined [OK]
Common Mistakes:
Using object instead of array for GlobalSecondaryIndexes
Wrong key types or missing HASH key
Incorrect property names like SecondaryIndexes
3. Given a DynamoDB table with a GSI on attribute Category (HASH key) and Price (RANGE key), what will the following query return?
A. All items where Price is greater than 20 regardless of Category
B. All items where Category is 'Books' or Price is greater than 20
C. All items where Category is 'Books' and Price is greater than 20
D. Syntax error because Price cannot be used in KeyConditionExpression
Solution
Step 1: Understand KeyConditionExpression with GSI keys
The query uses the GSI's HASH key 'Category' with equality and RANGE key 'Price' with a greater than condition, which is valid.
Step 2: Interpret the query filter
The query returns items where Category equals 'Books' AND Price is greater than 20, matching the GSI keys.
Final Answer:
All items where Category is 'Books' and Price is greater than 20 -> Option C
Quick Check:
GSI query with HASH and RANGE keys = All items where Category is 'Books' and Price is greater than 20 [OK]
Hint: GSI query uses HASH = and RANGE with conditions correctly [OK]
Common Mistakes:
Confusing AND with OR in KeyConditionExpression
Thinking Price can't be in KeyConditionExpression
Assuming query returns all items ignoring Category
4. You created a GSI with IndexName: 'UserEmailIndex' on attribute Email as HASH key. Your query on this GSI returns no results even though items with matching emails exist. What is the most likely cause?
medium
A. The GSI was created after the items were inserted and has not yet indexed them
B. You used the primary key instead of the GSI key in the query
C. The Email attribute is not projected to the GSI
D. DynamoDB does not support querying on GSIs
Solution
Step 1: Understand GSI indexing timing
When a GSI is created after data insertion, it takes time to index existing items. Queries may return empty until indexing completes.
Step 2: Evaluate other options
You used the primary key instead of the GSI key in the query is about query keys but question states query is on GSI. The Email attribute is not projected to the GSI is invalid because HASH key attributes must be projected automatically. DynamoDB does not support querying on GSIs is false; DynamoDB supports GSI queries.
Final Answer:
The GSI was created after the items were inserted and has not yet indexed them -> Option A
Quick Check:
New GSI indexing delay causes empty query [OK]
Hint: New GSI needs time to index existing data before queries work [OK]
Common Mistakes:
Assuming GSI queries always return instantly after creation
Confusing projection with key attributes
Believing DynamoDB doesn't support GSI queries
5. You have a DynamoDB table with a primary key UserID (HASH) and a GSI named OrderDateIndex with OrderDate as HASH and Status as RANGE key. You want to efficiently find all orders placed on '2023-05-01' with status 'Shipped'. Which query approach is best?
hard
A. Use a Scan on the GSI with FilterExpression for OrderDate and Status
B. Query the OrderDateIndex with KeyConditionExpression 'OrderDate = :date and Status = :status'
C. Query the main table with KeyConditionExpression 'UserID = :user and Status = :status'
D. Scan the table filtering for OrderDate and Status attributes
Solution
Step 1: Identify the best index for the query
The GSI OrderDateIndex has OrderDate as HASH and Status as RANGE key, matching the query conditions.
Step 2: Choose efficient query method
Querying the GSI with KeyConditionExpression on HASH and RANGE keys is efficient and uses indexes. Scans are less efficient and should be avoided.
Final Answer:
Query the OrderDateIndex with KeyConditionExpression 'OrderDate = :date and Status = :status' -> Option B
Quick Check:
Use GSI query with HASH and RANGE keys for best performance [OK]
Hint: Query GSI with HASH and RANGE keys, avoid scans for efficiency [OK]
Common Mistakes:
Using Scan instead of Query causing slow performance
Querying main table with wrong keys
Filtering after Scan instead of using KeyConditionExpression
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.