-
Notifications
You must be signed in to change notification settings - Fork 141
DynamoDB GSI Example
This is an example showing how to use spring-data-dynamodb to create a domain model and a repository class that will perform query's on a global secondary index. We will build on the example provided in the DynamoDB Hash Key Example which creates a DynamoDB table that stores customer information for a shopping cart system. It is a good idea to read through that example first.
We already have a table that has a unique identifier, an email address, and both the first and last name of the customer. We can already find a customer by their unique identifier, but we would want to search for a customer based upon their email address. Let's modify the table definition so that it includes a GSI on the emailAddress field.
{
"AttributeDefinitions": [
{
"AttributeName": "id",
"AttributeType": "S"
},
{
"AttributeName": "emailAddress",
"AttributeType": "S"
},
{
"AttributeName": "firstName",
"AttributeType": "S"
},
{
"AttributeName": "lastName",
"AttributeType": "S"
}
],
"KeySchema": [
{
"AttributeName": "id",
"KeyType": "HASH"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": "10",
"WriteCapacityUnits": "10"
},
"GlobalSecondaryIndexes": [
{
"IndexName": "idx_global_emailAddress",
"KeySchema": [
{
"AttributeName": "emailAddress",
"KeyType": "HASH"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"ProvisionedThroughput": {
"ReadCapacityUnits": 10,
"WriteCapacityUnits": 10
}
}
],
"TableName": "customer"
}
The definition above translates pretty simply into a domain model object like this:
@DynamoDBTable( tableName = "customer" )
public class Customer {
@Id
@DynamoDBHashKey
@DynamoDBAutoGeneratedKey
private String id;
@DynamoDBIndexHashKey(globalSecondaryIndexName = "idx_global_emailAddress")
private String emailAddress;
private String firstName;
private String lastName;
public Customer(String id, String emailAddress, String firstName, String lastName) {
this.id = id;
this.emailAddress = emailAddress;
this.firstName = firstName;
this.lastName = lastName;
}
public String getId() {
return id;
}
public String setId(String id) {
this.id = id;
}
public String getEmailAddress() {
return emailAddress;
}
public String setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getFirstName() {
return firstName;
}
public String setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public String setLastName(String lastName) {
this.lastName = lastName;
}
}
The only difference from the previous example is the addition of the @DynamoDBIndexHashKey annotation on the emailAddress field which indicates the name of the index in the DynamoDB table.
Finally, we will add a new method to the CustomerRepository class using the spring-data "findBy" formatting to indicate which fields to search upon. Here is what the CustomerRepository class looks like now:
public interface CustomerRepository extends CrudRepository<Customer, String> {
public List<Customer> findByEmailAddress(String emailAddress);
}
When spring-data-dynamodb is invoked through spring-data it will search for the @DynamoDBIndexHashKey annotation on the emailAddress field. When it finds it with an index name it will create and send a Query request to DynamoDB. Spring-data-dynamodb will create and send a Scan request to DynamoDB if the @DynamoDBIndexHashKey annotation was not found and there is an @EnableScan annotation on either the CustomerRepository class or on the findbyEmailAddress method.