2019-01-06
aws-go-sdk documentation doesn’t say much about how to use Expression Attribute Names, or what to do, when one of your attribute names is a reserved word of DynamoDb. Let me fill the hole.
Each examples below are using the Scan API.
In this basic example, sensorID is the primary partition key.
// Declare ScanInput parameters
// The ones without value will be nil, thus ignored by the request
var expressionAttributeNames map[string]*string
var expressionAttributeValues map[string]*dynamodb.AttributeValue
var filterExpression *string
var projectionExpression *string
// Create an attribute value mapping, so we are able to use :id in the filter expression
expressionAttributeValues = map[string]*dynamodb.AttributeValue{
":id": {
S: aws.String(*SensorID),
},
}
filterExpression = aws.String("sensorID = :id")
// ProjectionExpression is nil, so we receive all Item attributes in response
params := &dynamodb.ScanInput{
ExpressionAttributeNames: expressionAttributeNames,
ExpressionAttributeValues: expressionAttributeValues,
FilterExpression: filterExpression,
ProjectionExpression: projectionExpression,
TableName: aws.String(os.Getenv("TABLE_NAME")),
}
results, err := svc.Scan(params)
if err != nil {
return Response{}, err
}
// Iterate results
for _, i := range results.Items {
...
}
In this example, which is basically identical to the previous one, venueID is the primary sort key. I just wanted to demonstrate, that the use of API and parameters is not changing compared to the previous scenario.
// Declare ScanInput parameters
// The ones without value will be nil, thus ignored by the request
var expressionAttributeNames map[string]*string
var expressionAttributeValues map[string]*dynamodb.AttributeValue
var filterExpression *string
var projectionExpression *string
// Create an attribute value mapping, so we are able to use :id in the filter expression
expressionAttributeValues = map[string]*dynamodb.AttributeValue{
":v": {
S: aws.String(*VenueID),
},
}
filterExpression = aws.String("venueID = :v")
// ProjectionExpression is nil, so we receive all Item attributes in response
params := &dynamodb.ScanInput{
ExpressionAttributeNames: expressionAttributeNames,
ExpressionAttributeValues: expressionAttributeValues,
FilterExpression: filterExpression,
ProjectionExpression: projectionExpression,
TableName: aws.String(os.Getenv("TABLE_NAME")),
}
results, err := svc.Scan(params)
if err != nil {
return Response{}, err
}
// Iterate results
for _, i := range results.Items {
...
}
Now things are getting exciting. In this example venueID is stays the primary sort key, but we also use state in the expression, which is a keyword reserved by DynamoDb. See the extensive list of reserved keywords here.
// Declare ScanInput parameters
// The ones without value will be nil, thus ignored by the request
var expressionAttributeNames map[string]*string
var expressionAttributeValues map[string]*dynamodb.AttributeValue
var filterExpression *string
var projectionExpression *string
// Create a mapping which replaces "state" word with "#parking_state", so we don't use a reserved word in our expression
expressionAttributeNames = map[string]*string{
"#parking_state": aws.String("state"),
}
// Create an attribute value mapping, so we are able to use :id in the filter expression
expressionAttributeValues = map[string]*dynamodb.AttributeValue{
":v": {
S: aws.String(*VenueID),
},
":s": {
N: aws.String(*StateID),
},
}
// In the expression use "#parking_state" instead of "state"
filterExpression = aws.String("#parking_state = :s AND venueID = :v")
// ProjectionExpression is nil, so we receive all Item attributes in response
params := &dynamodb.ScanInput{
ExpressionAttributeNames: expressionAttributeNames,
ExpressionAttributeValues: expressionAttributeValues,
FilterExpression: filterExpression,
ProjectionExpression: projectionExpression,
TableName: aws.String(os.Getenv("TABLE_NAME")),
}
results, err := svc.Scan(params)
if err != nil {
return Response{}, err
}
// Iterate results
for _, i := range results.Items {
...
}
I hope these snippets will help you write complex Filter Expressions using Go SDK.