Reputation: 2695
I have the following code in a NodeJS 12x Lambda function:
targetedAliases = ["abc", "efg"]; //Not used yet. But want to replace alias with this array.
alias = "abc" //using this one aka targetedAliases[0].
const dynamoDB = new AWS.DynamoDB({
apiVersion: "2012-10-08"
});
var aliasScores;
const params = {
TableName: 'a-table',
FilterExpression: '#alias = :alias',
ExpressionAttributeNames: {
'#alias': 'alias',
},
ExpressionAttributeValues: {
':alias': {
S: alias
},
}
};
aliasScores = await dynamoDB.scan(params).promise();
console.log("====> ", aliasScores);
The function as is prints the content of aliasScores
as expected but I need to execute this n
times for each item on the targetedAliases
array.
Is there a way I can use a Array.forEach
or something similar to execute a query/scan iteratively for each item in an array? Alternatively, can I use an array on the FilterExpression
to execute the query/scan just once?
I want store each query/scan result in the aliasScores
variable as a concatenation of all returned objects to use it further below.
Upvotes: 0
Views: 1751
Reputation: 544
Your options kinda depend on whether the attribute alias is a primary key or not. Just knowing this difference will help a lot.
Promise.all() executes one operation for each alias. Consider the batch approach. A single batch for executes in one API invocation which will reduce the number of operations and reduce your DynamoDB API calls. Batching is fun.
When the attribute key 'alias' is the primary key, BatchGetItem a is very efficient operation for up to a dozen or so operations where each operation is a query for one alias. Just create a single BatchGetItem with one operation for each entry in the array. The response is a single json dictionary.
When the attribute key 'alias' is not the primary key then it's different because the table must be scanned. A DynamoDB scan() is different than a DynamoDB query(). scan can find items by any attribute and can filter by the value of 'alias.' The FilterExpression supports OR and it is possible to filter the scan. The scan will check every item and the filter just reduces the returned result set. The response is a single json dictionary.
Upvotes: 1
Reputation: 7770
You can use Promise.all
with .map
to execute these in parallel and get the results in array. Something like this
const targetedAliases = ["abc", "efg"]; //Not used yet. But want to replace alias with this array.
alias = "abc" //using this one aka targetedAliases[0].
const dynamoDB = new AWS.DynamoDB({
apiVersion: "2012-10-08"
});
var aliasScores;
const result = await Promise.all(targetedAliases.map(alias => {
const params = {
TableName: 'a-table',
FilterExpression: '#alias = :alias',
ExpressionAttributeNames: {
'#alias': 'alias',
},
ExpressionAttributeValues: {
':alias': {
S: alias
},
}
};
return dynamoDB.scan(params).promise();
}));
console.log(result);
Upvotes: 3