While trying to implement a DynamoDB scan within a Lambda function using the AWS SDK for JS (version 2.1051.0) I am facing some unexpected behavior.
I have a DynamoDB table named group
with exactly one item in it. The primary key for the objects is _id
but I want to scan all objects and want to filter by another attribute named groupOwner
.
I implemented a function which looks like the one below. It should retrieve all items of the Dynamo DB table where the attribute groupOwner
is equal john
. (Which by accident happens to apply to the only item of the table.)
const db = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: "group",
ExpressionAttributeValues: {
':username': {
S: "john"
}
},
FilterExpression: 'groupOwner = :username'
};
console.log("Params: "+JSON.stringify(params))
const queryResponse = await db.scan(params).promise();
console.log("Query response: "+ JSON.stringify(queryResponse))
Within the query response I expect to find the only object as result.
According to the Cloudwatch logs the scan + filter yields to an empty response. There are no items within the query response:
2022-01-07T15:56:01.822Z f20009ef-067a-4b7f-9c5c-fe34b80167ca INFO Params: {
"TableName": "group",
"ExpressionAttributeValues": {
":username": {
"S": "john"
}
},
"FilterExpression": "groupOwner = :username"
}
2022-01-07T15:56:02.363Z f20009ef-067a-4b7f-9c5c-fe34b80167ca INFO Query response: {
"Items": [],
"Count": 0,
"ScannedCount": 1
}
Naturally I was thinking I messed up the filter expression and tinkered around. But after some failed attempts I tried to recreate the problem using the AWS console and AWS CLI. Using the same parameters, both alternative solutions produce a correct response.
Running the command below returned the filtered object. Note that all the parameters of are the same as in the AWS SDK.
aws dynamodb scan --table-name group \
--expression-attribute-values '{":username":{"S": "john"}}' \
--filter-expression "groupOwner = :username" \
--output json
Output:
{
"Items": [
{
"_id": {
"S": "a677968a-3d8b-40f2-806c-3ea32237b755"
},
"groupMember": {
"L": []
},
"groupName": {
"S": "My New Group"
},
"groupOwner": {
"S": "john"
},
"blockedMember": {
"L": []
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
Also using the intuitive Web UI, I was able to see the expected result: AWS console screenshot
I cannot figure out why this JS snippet is not working for me and I hope you could help me identify what I've been doing wrong.
Already thank you in advance!
You are using the SDK's DocumentClient, which:
simplifies working with items in Amazon DynamoDB by abstracting away the notion of attribute values. This abstraction annotates native JavaScript types supplied as input parameters, as well as converts annotated response data to native JavaScript types
Change your filter parameters to:
const params = {
TableName: "group",
ExpressionAttributeValues: {
":username": "john"
},
FilterExpression: "groupOwner = :username"
};