@tables-indexes
Defines Global Secondary Indexes for your project’s DynamoDB tables. @tables-indexes
should only ever be paired with @tables
.
ℹ️ As of Architect v9.4,
@tables-indexes
should be used in place of@indexes
.@indexes
will be superseded in a future Arc release.
Recommended Resources
DynamoDB is a powerful database, though different from both SQL and NoSQL databases. It is highly recommended to dig into Amazon’s resources to familiarize yourself with it:
- DynamoDB Core Components (start here!)
- Global Secondary Indexes in DynamoDB
- Amazon’s full DynamoDB documentation
Syntax
@tables-indexes
is a feature subset of@tables
; as such, the names of your declared indexes must match those of your@tables
- AWS supports a maximum of 20 indexes per table
- Otherwise, the basic syntax for defining
@tables-indexes
primary keys is the same as@tables
:- Partition key, defined by a
*
, is required - Sort key, defined by
**
, is optional - Currently only
*String
,**String
,*Number
and**Number
are supported
- Partition key, defined by a
- An optional
name
property can be provided to explicitly name the index. This is helpful when querying the index with the AWS SDK as you know what to pass to theIndexName
query parameter - An optional
projection
property can be provided to explicitly define which item attributes get projected, or included, in query results. By default, Arc will project all item attributes (theALL
projection type as described in the DynamoDB documentation on attribute projections)- Customizing which attributes to project can be helpful when trying to save on storage costs
- Note that once a projection is defined, it cannot be changed; a new index would need to be created
- Acceptable values for
projection
are:all
(default): all item attributes from the table are projected into the indexkeys
: only the base table and index primary keys (and sort keys, if defined) are projected into the index- Custom: otherwise, you may define one or more attribute names to explicitly project into the index. Note that the base table and index keys always get projected
Deployment Considerations
⚠️ Be careful when arc deploy
indexes! There are a few unique CloudFormation behaviors that happen behind the scenes that you should be aware of, please see the Important note on the CloudFormation reference page for Global Secondary Indexes. In particular:
- Creating a new index on an existing table can take time. While the index is being populated, you cannot update the table or use the index. Furthermore, CloudFormation will not block while the index is populating, so you should keep tabs on its state after creation.
- CloudFormation generally does not support index updating, aside from a few specific properties.
- You can only add or delete one index in each deploy.
Given the above, it’s generally recommended to silo application updates to just the bare minimum when working with indexes.
Example
The following app.arc
file defines a DynamoDB table with two named Global Secondary Indexes, both with projection
explicitly defined:
arc
@app
testapp
@tables
accounts
accountID *String
@tables-indexes
accounts
email *String
projection keys # only project base table and index keys (in this example that would be accountID and email)
name byEmail
accounts
created *String
projection updated lastAccessed # only project base table and index keys plus the updated and lastAccessed attributes
name byDate
json
{
"app": "testapp",
"tables": [
{ "accounts": { "accountID": "*String" } }
],
"indexes": [
{ "accounts": { "email": "*String", "name": "byEmail", "projection": "keys" } },
{ "accounts": { "created": "*String", "name": "byDate", "projection": [ "updated", "lastAccessed" ] } }
]
}
yaml
---
app: testapp
tables:
- accounts:
accountID: "*String"
tables-indexes:
- accounts:
- email: "*String"
- name: "byEmail"
- projection: "keys"
- accounts:
- created: "*String"
- name: "byDate"
- projection: ["updated", "lastAccessed"]