Reputation: 17
I have a DynamoDB table where I would like to return all Items whose Review.ID mapped value is equal to 123.
Item: {
id: 1,
review: {
Id: 123,
step1: 456,
step2: 789,
step3: 1234,
},
// Add more items here
},
Item: {
id: 2,
review: {
Id: 123,
step1: 999,
step2: 888,
step3: 777,
},
// Add more items here
},
Ideal Return Example:
id: 1,
review: {
- id: 123,
- step: 456,
- step2: 789,
- step3: 1234,
}
id: 2,
review: {
- id: 123,
- step: 999,
- step2: 888,
- step3: 777,
}
This is my current code in NodeJS
exports.handler = async (event, context, callback) => {
const params = {
FilterExpression: "review.Id = :review",
ExpressionAttributeValues: {
":review": 123,
},
TableName: "sometable"
};
let promise = dynamoDb.scan(params).promise();
let result = await promise;
let data = result.Items;
if (result.LastEvaluatedKey) {
params.ExclusiveStartKey = result.LastEvaluatedKey;
data = data.concat(await (params));
}
// create a response
const response = {
statusCode: 200,
body: JSON.stringify(data),
};
callback(null, response);
};
Running this code I get an empty result [].
Any help on this would be greatly appreciated.
Upvotes: 0
Views: 479
Reputation: 78880
You haven't shown all your code but I am going to suggest that the problem is that your dynamoDb
client is the low-level DynamoDB Client rather than the high-level Document Client. They use different ways of supplying attribute values. You're using the low-level DynamoDB client but indicating attribute values as if you're using the high-level Document Client.
Here's an example that contrasts the two client approaches:
const AWS = require('aws-sdk');
AWS.config.update({ region: 'us-east-1' });
// High-level Document Client
const dc = new AWS.DynamoDB.DocumentClient();
// High-level scan parameters for Document Client
const paramsDC = {
FilterExpression: "review.Id = :review",
ExpressionAttributeValues: {
":review": 123,
},
TableName: "sometable"
};
// Low-level DynamoDB Client
const db = new AWS.DynamoDB();
// Low-level scan parameters for DynamoDB Client
const paramsDB = {
FilterExpression: "review.Id = :review",
ExpressionAttributeValues: {
":review": { "N": "123" },
},
TableName: "sometable"
};
(async() => {
// High-level scan
const resultDC = await dc.scan(paramsDC).promise();
console.log('DC Items:', JSON.stringify(resultDC.Items));
// Low-level scan
const resultDB = await db.scan(paramsDB).promise();
console.log('DB Items:', JSON.stringify(resultDB.Items));
})();
This results in:
DC Items: [{"review":{"step":999,"id":123},"id":2},{"review":{"step":456,"id":123},"id":1}]
DB Items: [{"review":{"M":{"step":{"N":"999"},"id":{"N":"123"}}},"id":{"N":"2"}},{"review":{"M":{"step":{"N":"456"},"id":{"N":"123"}}},"id":{"N":"1"}}]
Note that the low-level DynamoDB Client response looks a little different but is actually just a different (unmarshalled) representation of the same results. It includes "id":{"N":"1"}
which says that id
is a number with value 1
where the Document Client shows "id":1
. The low-level results includes "M": { ... }
which are maps, while the high-level Document Client unmarshalls these to JavaScript objects for you automatically.
Bottom-line:
Upvotes: 3