DynamoDB Advanced Operations using AWS GO SDK
This tutorial helps you to understand and code advanced DynamoDB operations using GO AWS SDK.
DynamoDB advanced Operations
Table Details:
Partition Key: userIdNo Sort Key
Global Secondary Index: organization
DynamoDB json:
{
"userId": {
"S": ""
},
"firstName": {
"S": ""
},
"lastName": {
"S": ""
},
"organization": {
"S": ""
}
}
DynamoDB Table Item's
userId | FistHName | LastName | Organization | |
---|---|---|---|---|
1 | WD001 | Rick | Grimes | walking dead |
2 | DC0013 | joker | joker | dc |
3 | WD002 | Maggie | Greene | walking dead |
GO Code prerequisite
To Create AWS Session:
region := "ap-south-1"
awsSession, _ := session.NewSession(&aws.Config{
Region: aws.String(region)},
)
To Create AWS DynamoDB Client:
dynaClient := dynamodb.New(awsSession)
DynamoDB Query
- Required attribute: Partition key. Query operation will result all the results with that partition key.
- Optional attribute: Sort key, FilterExpression Sort key can be used with comparison operator to refine search result.
- Query operation will always return a result set as response. If no matching items are found the result will be empty.
FilterExpression can be used to filter within result set. However the limit of result set 1MB will be considered before applying the filter.
//Get User details based on Global secondary index
func GetAdvancedUsers(organization string) ([]UserInfoAdvanced, error) {
users := []UserInfoAdvanced{}
tableName := "UserInfo"
region := "ap-south-1"
awsSession, _ := session.NewSession(&aws.Config{
Region: aws.String(region)},
)
dynaClient := dynamodb.New(awsSession)
var queryInput = &dynamodb.QueryInput{
TableName: aws.String(tableName),
IndexName: aws.String("organization-index"),
KeyConditions: map[string]*dynamodb.Condition{ //Only can add sort key, primary key or created index (GSI)
"organization": {
ComparisonOperator: aws.String("EQ"),
AttributeValueList: []*dynamodb.AttributeValue{
{
S: aws.String(organization),
},
},
},
},
}
var resp, errQueryDynamoDB = dynaClient.Query(queryInput)
if errQueryDynamoDB != nil {
errorString := "Table Lookup Error" + errQueryDynamoDB.Error()
fmt.Println(errorString)
return users, errQueryDynamoDB
}
if len(resp.Items) > 0 {
errUnMarshal := dynamodbattribute.UnmarshalListOfMaps(resp.Items, &users)
if errUnMarshal != nil {
errorString := "Unmarshal users Error" + errUnMarshal.Error()
fmt.Println(errorString)
return users, errUnMarshal
}
} else {
errorString := "Users Not found for Organization: " + organization
fmt.Println(errorString)
return users, errors.New(errorString)
}
fmt.Println("Successfully Fetched " + strconv.FormatInt(*resp.Count, 10) + " results from DynamoDB for Organization: " +
organization)
return users, nil
}
Input:
GetAdvancedUsers("DC0013")Output:
Successfully Fetched 1 results from DynamoDB for Organization: dc[{DC0013 joker joker dc}]
Query with filter and projection
Input:
GetUsersQueryFilterProjection("walking dead", "Rick")Output:
Successfully Fetched 1 results from DynamoDB for Organization: walking dead, First Name: Rick [{WD001 Rick Grimes }]Get Batch Items
Limitation: Max 100 Primary Keys
- Can request maximum of 100 items and max size of 16MB.
- If result set is greater than 16MB, the UnprocessedKeys in the response will be non empty.
- If we request more than 100 items ValidationException with the message "Too many items requested for the BatchGetItem call."
Input:
GetBatchUsersFromPrimaryKeys([]string{"WD001", "DC0013"})Output:
Successfully Fetched 2 results from DynamoDB[{WD001 Rick Grimes walking dead} {DC0013 joker joker dc}]
Paginations
If the result of Query/Scan if greater than 1MB data, we will get only the partial paginated result.
Single Query operation will retrieve only a maximum of 1 MB of data. This limit is before any FilterExpression is applied query to the results. If we are recieving a paginated result LastEvaluatedKey will be present in the response and is non-null.To Get the whole results we need to create input with ExclusiveStartKey. ExclusiveStartKey is the value obtained in result LastEvaluatedKey
var queryInput = &dynamodb.QueryInput{
TableName: aws.String(tableName),
IndexName: aws.String("organization-index"),
KeyConditions: map[string]*dynamodb.Condition{ //Only can add sort key, primary key or created index (GSI)
"organization": {
ComparisonOperator: aws.String("EQ"),
AttributeValueList: []*dynamodb.AttributeValue{
{
S: aws.String(organization),
},
},
},
},
ExclusiveStartKey: map[string]*dynamodb.AttributeValue{}, // which is same as LastEvaluatedKey from the initial response
}
Written by
Arun N
Full stack developer. Go |5x AWS Certified | Angular
AWS CERTIFIED DEVELOPER ASSOCIATE | SOLUTION ARCHITECT | DATABASE – SPECIALTY | DATA ANALYTICS – SPECIALTY| MACHINE LEARNING – SPECIALTY